Reputation: 12896
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;
}
Upvotes: 5
Views: 499
Reputation: 114461
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.
Upvotes: 1
Reputation: 145204
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.
Upvotes: 6