2009-04-12 7 views
48

Ich habe mich immer gefragt, warum Sie lokal definierte Klassen nicht als Prädikat für STL-Algorithmen verwenden können.Verwendung lokaler Klassen mit STL-Algorithmen

In der Frage: Approaching STL algorithms, lambda, local classes and other approaches, sagt BubbaT erwähnt, dass 'Da der C++ Standard lokale Typen verbietet als Argument verwendet werden sollte'

Beispielcode:

int main() { 
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
    std::vector<int> v(array, array+10); 

    struct even : public std::unary_function<int,bool> 
    { 
     bool operator()(int x) { return !(x % 2); } 
    }; 
    std::remove_if(v.begin(), v.end(), even()); // error 
} 

jemand, wo in der Weiß Standard ist die Beschränkung? Was ist der Grund dafür, lokale Typen zu verbieten?


EDIT: Da C++ 11, es legal ist, einen lokalen Typen als Template-Argument zu verwenden.

Antwort

50

Es ist explizit vom C++ 98/03-Standard verboten.

C++ 11 diese Einschränkung entfernen.

Um vollständigere:

Die Beschränkungen für Typen, die als Parameter Vorlage verwendet werden sind in Artikel 14.3.1 des C++ 03 (und C++ aufgelistet 98) Standard:

ein lokaler Typ, ein Typ ohne Gestänge, eine unbenannte Art oder einen Typ compoundiert von einem dieser Typen darf nicht verwendet als Template-Argument für einen Template Type-Parameter.

template <class T> class Y { /* ... */ }; 
void func() { 
     struct S { /* ... */ }; //local class 
     Y<S> y1; // error: local type used as template-argument 
     Y< S* > y2; // error: pointer to local type used as template-argument } 

Quelle und weitere Informationen: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420

Zusammenfassend war die Beschränkung einen Fehler, der früher festgelegt worden wäre, wenn der Standard schneller wurde weiterentwickelt ...

Das sagte heute die meisten letzten Versionen gewöhnlicher Compiler erlauben dies, zusammen mit Lambda-Ausdrücken.

+0

Ich weiß, aber ich würde gerne wissen, wo zu sehen ist, wenn ich verstehen kann, warum. Hast du einen Bezug zum Standard? –

+0

Beziehen Sie sich auf 14.3.1.2, "Vorlagenargumente"? – greyfade

+0

Ich habe einige Informationen und einen Link hinzugefügt, die helfen könnten. Zusammenfassend war die Beschränkung ein Fehler, der schnell behoben worden wäre, wenn der Standard schneller wurde weiterentwickelt ... – Klaim

5

Die Einschränkung wird in ‚0x entfernt werden, aber ich glaube nicht, dass Sie sie sehr viel würden verwenden. Und das ist, weil C++ - 0x Lambdas haben wird! :)

int main() { 
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
    std::vector<int> v(array, array+10); 

    std::remove_if(v.begin() 
       , v.end() 
       , [] (int x) -> bool { return !(x%2); }) 
} 

Meine Syntax in der oben kann nicht perfekt sein, aber die allgemeine Idee ist da.

+0

Ich wusste von Lambdas. In der Tat, was ich erreichen wollte, ist so nah wie möglich mit dem aktuellen Standard. Art der Lösung, die Java vorschlägt. –

+0

Und auf welche Weise ist das eine Antwort auf die eigentliche Frage (geschweige denn eine, die 4 Up-Stimmen wert ist)? –

+0

@ChristianRau:;) Ich kann sehen, warum du das sagst. Die Frage ist, warum sind sie nicht erlaubt und die erste Zeile der Antwort spricht das an. Es wurde entfernt, so dass es keinen guten Grund für die Einschränkung geben konnte. Zu der Zeit dachte ich eindeutig, dass lambdas erwähnenswert wären. Jetzt, 3 Jahre später, sind Lambdas bekannt und sie sind keine Neuigkeiten mehr! –