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

c++

Solution

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.

Problem

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; } ```

Original source

Related problems