2010-12-29 7 views
7

Il seguente codice non verrà compilato. Il compilatore si lamenta di * nessuna funzione di matching per la chiamata a for_each *. Perché è così?Perché non è possibile utilizzare una struct definita all'interno di una funzione come functor per 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()); 
} 

Quando sposto struct FlipFunctor prima funzione flip_all, il codice viene compilato.

messaggio di errore 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)’

risposta

13

std::for_each è un modello di funzione; uno dei parametri del modello è il tipo dell'argomento della funzione.

Non è possibile utilizzare un tipo locale come argomento modello. È solo una restrizione attualmente nella lingua. Nella prossima revisione di C++, C++ 0x, questa restrizione viene rimossa, quindi è possibile utilizzare i tipi locali come argomenti del modello.

Visual C++ 2010 supporta già l'utilizzo di classi locali come argomenti del modello; il supporto in altri compilatori può variare. Direi che qualsiasi compilatore che supporta C++ 0x lambda sosterrebbe anche l'uso delle classi locali come argomenti del template (questo potrebbe non essere del tutto vero, ma avrebbe senso).

+2

C++ 03: * Quasi * consente di definire opportunamente i funtori ad-hoc vicino ai loro punti di utilizzo. :-P –

0

ottengo un altro errore quando provo a compilare il codice:

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

che in realtà è da aspettarselo, perché un tipo locale di funzioni (come il tuo FlipFunctor qui) ha un collegamento interno e un tipo di modello deve avere un collegamento esterno. Poiché il terzo parametro di std :: for_each è un modello, non è possibile passare qualcosa di una funzione di tipo locale ad esso.

+2

Le classi locali non dispongono di collegamento interno; non hanno alcun collegamento –

+0

Tuttavia, il messaggio di errore è molto meglio del mio. Questo è gcc 4.5? – Oswald

+0

@Oswald: No, è GCC 4.0, su Mac OS X. –

Problemi correlati