The following code won't compile. The compiler complains about *no matching function for call to for_each*. Why is this so?
#include <map>
#include <algorithm>
struct Element
{
void flip() {}
};
void flip_all(std::map<Element*, Element*> input)
{
struct FlipFunctor
{
void operator() (std::pair<Element* const, Element*>& item)
{
item.second->flip();
}
};
std::for_each(input.begin(), input.end(), FlipFunctor());
}
When I move struct FlipFunctor
before function flip_all
, the code compiles.
Full error message:
no matching function for call to ‘for_each(std::_Rb_tree_iterator<std::pair<Element* const, Element*> >, std::_Rb_tree_iterator<std::pair<Element* const, Element*> >, flip_all(std::map<Element*, Element*, std::less<Element*>, std::allocator<std::pair<Element* const, Element*> > >)::FlipFunctor)’
std::for_each
is a function template; one of the template parameters is the type of the function argument.
You cannot use a local type as a template argument. It's just a restriction currently in the language. In the forthcoming revision of C++, C++0x, this restriction is removed, so you can use local types as template arguments.
Visual C++ 2010 already supports the use of local classes as template arguments; support in other compilers may vary. I'd guess that any compiler that supports C++0x lambdas would also support the use of local classes as template arguments (this may not be entirely true, but it would make sense).
I get a different error when I try to compile your code:
error: 'flip_all(__gnu_debug_def::map, std::allocator > >)::FlipFunctor' uses local type 'flip_all(__gnu_debug_def::map, std::allocator > >)::FlipFunctor'
That's actually to be expected, because a function local type (such as your FlipFunctor here) has internal linkage, and a template type must have external linkage. Since the third parameter of std::for_each is a template, you cannot pass something of a function local type to it.
来源:https://stackoverflow.com/questions/4550914/why-cant-a-struct-defined-inside-a-function-be-used-as-functor-to-stdfor-each