I'm trying to call a pointer function using a explicit dereference, but compiler throws an error: 'no operator "*" matches these operands'.
Here's simplified version of my code:
#include <functional>
#include <iostream>
int add(int a, int b)
{
return a b;
}
std::function<int(int, int)> passFunction()
{
return &add;
}
int main()
{
int a{ 1 };
int b{ 2 };
std::cout << (*passFunction())(a, b);
return 0;
}
The thing is, it works fine when I just write:
std::cout << passFunction()(a, b);
without asterix. Which blows my mind.
I thought I messed up parentheses in function call. I tried different order and precedence, I called it with ampersand, and still compiler doesn't even flinch.
CodePudding user response:
I'm trying to call a pointer function using a explicit dereference. But compiler throws an
error: 'no operator "*" matches these operands'
.
Type matters!
The return type of the passFunction
is not a pointer, rather std::function
. It is not something of dereferencable. Hence, you get the compiler error.
The thing is, it works fine when I just write:
std::cout << passFunction()(a, b);
without asterix [...]
The std::function
meant for invoking/ calling. That is why passFunction()(a, b)
works. It calls the operator()
of std::function
(i.e. equivalent to passFunction().operator()(a, b)
).
That been said, if you simply return the function by auto
(since C 14 - let the compiler deduce the type), you will get the actual function pointer, which you can call
either by dereferencing (unnecessary) or directly.
using fun_t = int(*)(int, int); // function pointer type
auto passFunction()
//^^^ use auto --> type == int(*)(int, int)
// or use fun_t
{
return &add;
}
now you can (unnecessary)
(*passFunction())(a, b);
or
passFunction()(a, b);
Now obvious question, "how the both syntax is possible ?". Read here in detail in the following posts:
- How does dereferencing of a function pointer happen?
- Calling a function through a function pointer - dereference the pointer or not? What's the difference?
- Why can we dereference a function pointer?
CodePudding user response:
but compiler throws an error: 'no operator "*" matches these operands'.
Your passFunction
returns a std::function<int(int, int)>
which as we can see from its documentation does not have any overloaded dereference operator. Thus we cannot write *passFunction()
. The correct syntax would be as shown below:
//------------v----------------------->removed the * as std::function does not overload any such operator
std::cout << ( passFunction())(a, b)
Or
//----------v------------------------>no need for dereferencing
std::cout << passFunction()(a, b);
CodePudding user response:
You shouldn't use the *
operator on the std::function<int(int, int)>
that passFunction()
returns since it doesn't return a pointer that needs to be dereferenced.
This simple example will do:
#include <functional>
#include <iostream>
int add(int a, int b) {
return a b;
}
std::function<int(int, int)> passFunction() {
return add; // or return &add - same thing when it comes to free functions
// as opposed to member functions
}
int main() {
int a{1};
int b{2};
std::cout << passFunction()(a, b);
}
I think the confusion comes from the fact that you do &add
to return a function pointer - but look at what's important: The return type:
std::function<int(int, int)>
This is what passFunction()
returns. It's not a pointer. It returns it by value. The function pointer you return
is merely used as an argument to the std::function<int(int, int)>
's constructor.