Home > Mobile >  How to call a function returning a function pointer?
How to call a function returning a function pointer?

Time:10-29

I am trying to call a function pointer using an explicit dereference. But the compiler throws an error:

no operator "*" matches these operands.

Here's a 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 that, 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:

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.

  • Related