Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I cannot pass a functor defined in a function to another function?

Tags:

c++

I found the functor can be used to simulate defining a function within a function like this

using namespace std;
int main(int argc, char* argv[])
{
    struct MYINC {
        int operator()(int a) { return a+1; }
    } myinc;
    vector<int> vec;
    for (int i = 0; i < 10; i++) vec.push_back(myinc(i));
    return 0;
}

But If I passed it to an outside function, such as std::transform like the following example, I've got a compiling error saying error: no matching function for call to ‘transform(std::vector<int>::iterator, std::vector<int>::iterator, std::vector<int>::iterator, main(int, char**)::MYINC&)’

using namespace std;
int main(int argc, char* argv[])
{
    struct MYINC{
        int operator()(int a) { return a+1; }
    } myinc;
    vector<int> vec;
    for (int i = 0; i < 10; i++) vec.push_back(i);
    transform(vec.begin(), vec.end(), vec.begin(), myinc);
    return 0;
}

So I put the definition outside the main function and all is OK now.

using namespace std;
struct MYINC{
    int operator()(int a) { return a+1; }
} myinc;
int main(int argc, char* argv[])
{
    vector<int> vec;
    for (int i = 0; i < 10; i++) vec.push_back(i);
    transform(vec.begin(), vec.end(), vec.begin(), myinc);
    return 0;
}
like image 623
Yantao Xie Avatar asked Feb 15 '14 06:02

Yantao Xie


People also ask

How do you pass a functor as a function?

You cannot pass a functor as a function pointer into a function that takes a function pointer, even if the functor has the same arguments and return value as the function pointer. Similarly, if a function expects a functor, you cannot pass in a function pointer.

What is the difference between a functor and a function pointer Why might we want to use a functor instead of a function pointer?

While either a functor or function would work, functors are actually more efficient since calling them does not require any indirection. The compiler can statically determine from the functor type which overloaded operator is called, while calling through a function pointer generally requires a dereference at runtime.

What is functor in c++?

A C++ functor (function object) is a class or struct object that can be called like a function. It overloads the function-call operator () and allows us to use an object like a function.

Whats the point of functors?

A function pointer allows a pointer to a function to be passed as a parameter to another function. Function Objects (Functors) - C++ allows the function call operator() to be overloaded, such that an object instantiated from a class can be "called" like a function.


2 Answers

Both versions compile fine with g++ 4.8.2, which is a C++11 compiler.

A C++03 compiler would however balk at instantiating a template with a local type, since that was not supported in C++03.

One solution, if that is indeed the root cause of the problem, is then to use a more recent compiler version or other compiler.

Another solution is to leverage that even in C++03 you can define a "real" function locally, by making it a static member function of a local class (in C++11 you can also do that by using a lambda expression).

However, except for dealing with such a problem, the functor has a general performance advantage over the "real" function, namely that with an object of a class instead of just a function pointer, and with the relevant operator() as inline, the compiler can optimize much better, because it knows the function implementation.

like image 185
Cheers and hth. - Alf Avatar answered Sep 25 '22 14:09

Cheers and hth. - Alf


For reasons that aren't entirely clear to me there is (was) a well-known and quite annoying limitation in C++ 03 on which types you can use to instantiate a template.

Locally defined classes could not be used as parameters with templates, just because.

This by the way made quite difficult to make any decent use of the <algorithm> library because you could not keep the context of your code local, being forced instead to place all functors, comparators and the like at namespace level, making up funny names for them and placing them far from the point of use.

like image 30
6502 Avatar answered Sep 23 '22 14:09

6502