error: invalid use of void expression, C++ [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am trying to implement a Menu system for a school project, where I have a STL Map containing function pointers in the form of
map<string, YMenu>
When I try to call a member function from within YMenu to add a new function pointer to a vector through the map, I get an error saying that it's an "invalid use of void expression." I have attached the relevant code below.
Vector holding arrays:
vector<void (*) () > nextAction;
Function to add function pointers:
void YMenu::addNextAction(int index, void (*Action)() )
{
nextAction[index] = Action;
}
Syntax used when calling member function which generated the Error:
Menus["0.0"].addNextAction(1, Menus["0.1"].show());
Any ideas for possible solutions? I have tried to find on google and searching here but can't seem to find an answer. :/
SOLVED: Thanks guys, apparently I made some stupid mistakes back there. I have finally managed to implement the code and get it to compile and run by using std::function and std::bind().

The type of Menues["0.1"].show() isn't a function pointer. It is the result of calling show() on a specific object. It seems, your show() function returns int. You won't have much fun trying to shove the function into a void(*)() in any shape or form!
What you are probably looking for is std::function<void()> which can be used to invoke a nullary function object, i.e., something which can be called without a parameter. The function you want to pass seems to be a member function and as such it actually has a parameter, the implicitly passed this pointer. You also want to ignore the return type which std::function<void()> will happily to do for you. That is, your nextAction vector would be declared as
std::vector<std::function<void()> nextAction;
However, to actually add the show function with the correct object, you need to also construct a suitbale std::function<void()> object: since your member function needs an object, you'll need to bind the object to the function, e.g.:
Menues["0.0"].addNextAction(1, std::bind(&YMenu::show, &Menus["0.1"]));
Also note that using nextAction[index] is only valid if index < nextAction.size() prior to this operation, i.e., std::vector<T> doesn't automatically resize to the proper size to accommodate a new index: that has to be explicitly for std::vector<T>.

With Menus["0.1"].show() you are calling the function.
You also can't store pointers to member functions like you try to do, unless you actually have the object instance when you finally call the member function pointer. I suggest you look into std::function and std::bind:
std::vector<std::function<void()> nextAction;
nextAction.push_back(std::bind(&YMenu::show, &Menus["0.1"]));

Instead of using C-style function pointers, use a combination of std::function and std::bind as follows:
std::vector<std::function<void()> > nextAction;
void YMenu::addNextAction(int index, std::function<void()> Action)
{
nextAction[index] = Action;
}
Menus["0.0"].addNextAction(1, std::bind(&YMenu::show, &Menus["0.1"]));

Related

Function Pointer Initialization in C/C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 months ago.
Improve this question
As I was going through a ESP IDF's documentation; I saw that a function pointer was initialized in a certain way that does not make sense to me.
typedef void *app_driver_handle_t;
app_driver_handle_t app_driver_light_init();
app_driver_handle_t app_driver_button_init();
Etc.
I thought that in order to initialize a function pointer, you must do it the following way:
app_driver_handle_t = app_driver_button_init();
Sorry for my beginner level questions.
It would do wonders if someone could explain this.
Thanks
Let's break down the code you're looking at.
typedef void *app_driver_handle_t;
This is not a function pointer. This is a void pointer, which means it can point to basically any values. And this is a type, not a value, so app_driver_handle_t does not actually contain any pointers at all; it's merely a name that's synonymous with void*.
app_driver_handle_t = app_driver_button_init();
Given the typedef above, this syntax is never valid. You're setting a type equal to what is presumably a function call. You can't assign to types. Full stop.
What you can do is declare variables and assign them the result of function calls.
app_driver_handle_t my_variable;
my_variable = app_driver_button_init();
or you can do it in one line.
app_driver_handle_t my_variable = app_driver_button_init();
Finally, these last two lines.
app_driver_handle_t app_driver_light_init();
app_driver_handle_t app_driver_button_init();
These are also not function pointers. These are function prototypes. They're a promise to the compiler, saying, "I will eventually define two functions called app_driver_light_init and app_driver_button_init. These two functions will take no arguments and will return a void*". There's still no function pointer happening here. The functions, when they're eventually defined, will return a void*, which, again, is not a function pointer but a pointer to void.
This is effectively same as
void * app_driver_light_init();
void * app_driver_button_init();
These are not function pointers, they are functions that return void*.
A typedef'd fucntion pointer would look like this:
typedef void* (*app_driver_light_init)();

Specific C++ notation for function arguments? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
This is a simple question, but I couldn't find the answer through searching online. I was trying to work through some leetcode problems to better my understanding of C++. I was wondering if someone could walk me through the meaning behind the creation of this function.
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
}
};
I understand that public is used so that we can access ____ outside the Solution class, but I am not sure what exactly... it also looks like we are initializing a vector of integers named "twoSum" with the arguments of a vector of numbers and a target value... I was wondering what the meaning of the & is... etc. I guess a simple question would be can someone translate this block of code so that I can write my own versions for various problems (it seems like this is a constant block (or variation of a similar block) of code that is common throughout these leetcode problems).
The shown code snippet, defines a member function named twoSum that has the return type of vector<int> and has 2 parameters. The first parameter named nums is an lvalue reference to a non-const vector<int> while the second parameter named target is an int.
I was wondering what the meaning of the & is
The & in the first parameter nums of the member function means that nums is an lvalue reference to a non-const vector<int>. Meaning, the argument that will be passed to the nums parameter, will be passed by reference instead of passed by value. That is, inside the member function twoSums, the nums refer to the original vector<int> that is passed as an argument.
Also note that there should be a return statement inside the member function since the return type of the member function is non-void.

Return a functor based on command line input [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
From command line input I am receiving a single char of '=','<', or '>' followed by a value and my goal is to iterate through and modify my underlying data container using a custom functor (for example using remove_if). The simple but slow solution would be to have a single functor that is constructed using the input char and switching between the operators within it. However, this requires a check on the operator type every time the functor's operator is called. My first solution was using a switch statement on the char and creating a base functor class with 3 derived classes. However, I realized that while this was a completely viable and fast solution, I ended up having a large amount of code duplication of the switch statements. My attempt at a solution to this was using polymorphism and having a function that accepted the input char and returned a pointer of the base class which had a virtual () operator. However, when I passed the dereferenced base class pointer, it would not accept a pure virtual() operator and it was not overriden by the operators of the derived classes. In a sense, I want a function that returns a particular lambda or comparator assosciated with the value of an input char. What would be a good way of going about this?
Since lambdas have there own type i am not aware of a way to construct a function that returns different lambdas. You could store them in std:: function and pay for the overhead.
I think a combination of function ptr and map might be a good solution. Consider using a constexpr map (like in https://youtu.be/INn3xa4pMfg), create your functions and store the mapping in that map.
Note that you can also convert a non capturing lambda to a funtion ptr using ClosureType::operator ret(*)(params)() (See https://en.cppreference.com/w/cpp/language/lambda).

std::tr1::function - store function objects of various types in common container

I'm converting my implementation of functor to std::tr1::function (the reason is that with my implementation we need to predefine type and functor class for each function type, I want to extend this to work with any function).
I have
int param = 1;
std::tr1::bind (&MyClass::func, param);
and I want to add this to some common container
someContainer.insert (std::tr1::bind (&MyClass::func, param));
so, how to declare the container, what type it must be to accept function of any type? Is it possible at all?
The second question - how to invoke functions in container, like this:
someContainer.begin().invoke();
P.S. Maybe there is another solution, I'm not aware enough in this topic. Would be thankful for answers.
I deal with GNU C++98.
If by "any type" you mean all function objects (functors) having the same signature, then it's easy:
std::vector< std::tr1::function<void()> > someContainer;
This will create a vector of any function objects that takes no parameters and returns void.
To invoke the function, just call it like a regular function object:
(*someContainer.begin()) ();

Disabling "bad function cast" warning

I'm receiving the following warning:
warning: converting from 'void (MyClass::*)(byte)' to 'void (*)(byte)'
This is because I need to pass as argument a member function instead of an ordinary function. But the program is running correctly.
I'd like to disable this warning (Wno-bad-function-cast doesn't work for C++) or to implement a different way to pass a member function.
No. Take this warning seriously. You should rather change your code to handle this scenario.
Pointer to member function(void (MyClass::*)(byte)) and normal function pointer (void (*)(byte)) are entirely different. See this link. You cannot cast them just like that. It results in undefined behavior or crash.
See here, how they are different:
void foo (byte); // normal function
struct MyClass {
void foo (byte); // member function
}
Now you may feel that, foo(byte) and MyClass::foo(byte) have same signature, then why their function pointers are NOT same. It's because, MyClass::foo(byte) is internally resolved somewhat as,
void foo(MyClass* const this, byte);
Now you can smell the difference between them.
Declare pointer to member function as,
void (MyClass::*ptr)(byte) = &MyClass::foo;
You have to use this ptr with the object of MyClass, such as:
MyClass obj;
obj.*ptr('a');
You can't pass a function that takes two arguments to a place that expects a function that takes one. Can't be done, forget about it, period, end of story. The caller passes one argument to your function. It doesn't know about the second argument, it doesn't pass it to your function, you can't make it do what you want however hard you try.
For the very same reason you can't pass a non-static member function where a regular function is expected. A member function needs an object to operate on. Whatever code calls your function doesn't know about the object, there's no way to pass it the object, and there's no way to make it use the right calling sequence that takes the object into account.
Interfaces that take user's functions, without taking additional data that the user might want to pass to his function, are inherently evil. Look at the qsort() function from the C standard library. That's an example of an evil interface. Suppose you want to sort an array of string according to some collation scheme defined externally. But all it accepts is a comparison function that takes two values. How do you pass that collation scheme to your comparison function? You can't, and so if you want it working, you must use an evil global variable, with all the strings attached to it.
That's why C++ has moved away from passing function pointers around, and towards function objects. Function objects can encapsulate whatever data you want.
Also, this may be helpful
union FuncPtr
{
void (* func)(MyClass* ptr, byte);
void (MyClass::* mem_func)(byte);
};