2010-12-29 6 views
7

Der folgende Code wird nicht kompiliert. Der Compiler beklagt sich über * keine passende Funktion für den Aufruf von for_each *. Warum ist das so?Warum kann eine in einer Funktion definierte Struktur nicht als Funktor für std :: for_each verwendet werden?

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

Wenn ich struct FlipFunctor vor Funktion flip_all bewegen, kompiliert den Code.

Vollfehlermeldung:

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

Antwort

13

std::for_each ist eine Funktionsvorlage; Einer der Template-Parameter ist der Typ des Funktionsarguments.

Sie können keinen lokalen Typ als Vorlagenargument verwenden. Es ist nur eine Einschränkung in der Sprache. In der nächsten Version von C++, C++ 0x, wird diese Einschränkung entfernt, sodass Sie lokale Typen als Vorlagenargumente verwenden können.

Visual C++ 2010 unterstützt bereits die Verwendung von lokalen Klassen als Vorlageargumente; Unterstützung in anderen Compilern kann variieren. Ich würde vermuten, dass jeder Compiler, der C++ 0x Lambda unterstützt, auch die Verwendung von lokalen Klassen als Template-Argumente unterstützen würde (dies mag nicht ganz richtig sein, aber es wäre sinnvoll).

+2

C++ 03: * Fast * ermöglicht Ihnen, ad-hoc Funktoren in der Nähe ihrer Verwendungspunkte bequem zu definieren. :-P –

0

ich einen anderen Fehler, wenn ich versuche, den Code zu kompilieren:

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

Das eigentlich ist zu erwarten, weil eine Funktion lokalen Typ (wie Ihre FlipFunctor hat hier eine interne Verknüpfung und ein Schablonentyp muss eine externe Verknüpfung haben. Da der dritte Parameter von std :: for_each eine Vorlage ist, können Sie etwas von einem lokalen Funktionstyp nicht übergeben.

+2

Lokale Klassen haben keine interne Verknüpfung; Sie haben keine Verbindung. –

+0

Die Fehlermeldung ist jedoch viel besser als meine. Ist das gcc 4.5? – Oswald

+0

@Oswald: Nein, das ist GCC 4.0, unter Mac OS X. –

Verwandte Themen