Why is the structure defined inside the function not used as a functor for std :: for_each?

The following code will not compile. The compiler complains about * the lack of a suitable function to call 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 the struct FlipFunctor before the flip_all function, the code compiles.

Full error message:

there is no corresponding function to call to_each (std :: _ Rb_tree_iterator <std :: pair <Element * const, Element *> gt ;, 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)

+7
source share
2 answers

std::for_each - function template; one of the template parameters is the type of the function argument.

You cannot use a local type as an argument to a template. This is simply a limitation currently in this language. In the upcoming C ++, C ++ 0x revision, 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 assume that any compiler that supports C ++ 0x lambdas will also support the use of local classes as template arguments (this may not be entirely true, but it makes sense).

+13
source

I get another error when trying to compile your code:

error: 'flip_all (__ gnu_debug_def :: map, std :: allocator β†’) :: FlipFunctor' uses the local type 'flip_all (__ gnu_debug_def :: map, std :: allocator β†’) :: FlipFunctor'

This can be expected because the local type of the function (for example, your FlipFunctor here) has an internal binding, and the template type must have an external binding. Since the third parameter std :: for_each is a template, you cannot pass it something from the local function type.

0
source

All Articles