0

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.

11
  • 4
    What gave you the idea that passFunction returns a pointer? What is the return type of that function? Commented Oct 28, 2022 at 16:46
  • 1
    Functions are always pointers at the assembly level. &add and add are the same. But, you do not return a pointer anyway. You return a std::function<int(int, int)> which gets initialized from &add, i.e. add. Commented Oct 28, 2022 at 16:47
  • 1
    Probably the & in return &add; caused the misconception. Commented Oct 28, 2022 at 16:48
  • 1
    std::function is an object, not a function pointer. To call the embedded call, so yes just use passFunction()(a,b); or auto fn = passFunction(); fn(a,b); Read more here en.cppreference.com/w/cpp/utility/functional/function (cppreference is the goto place for C++/standard library documentation) Commented Oct 28, 2022 at 16:49
  • 1
    @kvrier That is true. But std::function<int(int, int)> isn't a pointer, it's an object and there's no pointer in the return type of your function. Commented Oct 28, 2022 at 16:55

3 Answers 3

3

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:

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent answer! And this is also the only one that explains how int(*)(int, int) works, which is the fundamental cause of the misunderstanding here
0

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);

Comments

0

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.

2 Comments

Thank you for the answer! Is free function a term that refers to function that is a non-member function?
@kvrier Yes, indeed. I added that to the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.