2010-12-29 15 views
7

El siguiente código no se compilará. El compilador se queja de * ninguna función de coincidencia para la llamada a for_each *. ¿Por qué esto es tan?¿Por qué no se puede usar una estructura definida dentro de una función como functor para std :: for_each?

#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()); 
} 

Cuando muevo struct FlipFunctor antes de la función flip_all, el código se compila.

mensaje de error completo:

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)’

Respuesta

13

std::for_each es una plantilla de función; uno de los parámetros de la plantilla es el tipo de argumento de la función.

No puede usar un tipo local como argumento de plantilla. Es solo una restricción actualmente en el idioma. En la próxima revisión de C++, C++ 0x, esta restricción se elimina, por lo que puede usar tipos locales como argumentos de plantilla.

Visual C++ 2010 ya admite el uso de clases locales como argumentos de plantilla; el soporte en otros compiladores puede variar. Supongo que cualquier compilador que admita C++ 0x lambdas también admitiría el uso de clases locales como argumentos de plantilla (esto puede no ser del todo cierto, pero tendría sentido).

+2

C++ 03: * Casi * que le permite convenientemente definir funtores ad-hoc cerca de sus puntos de uso. :-PAG –

0

me sale un error diferente cuando intento compilar el código:

error: 'flip_all(__gnu_debug_def::map, std::allocator > >)::FlipFunctor' uses local type 'flip_all(__gnu_debug_def::map, std::allocator > >)::FlipFunctor'

que en realidad es de esperar, debido a un tipo local de la función (como su FlipFunctor aquí) tiene un enlace interno, y un tipo de plantilla debe tener un enlace externo. Como el tercer parámetro de std :: for_each es una plantilla, no puede pasarle algo de una función de tipo local.

+2

Las clases locales no tienen enlace interno; ellos no tienen ningún enlace. –

+0

El mensaje de error es mucho mejor que el mío, sin embargo. ¿Es este gcc 4.5? – Oswald

+0

@Oswald: No, eso es GCC 4.0, en Mac OS X. –

Cuestiones relacionadas