2009-04-12 8 views
48

Mi sono sempre chiesto perché non è possibile utilizzare classi definite localmente come predicati per gli algoritmi STL.Utilizzo di classi locali con algoritmi STL

Nella domanda: Approaching STL algorithms, lambda, local classes and other approaches, BubbaT menziona dice che 'Poiché lo standard C++ vieta tipi locali da utilizzare come argomenti'

codice Esempio:

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 
} 

Qualcuno sa dove nel lo standard è la restrizione? Qual è la logica per non consentire i tipi locali?


EDIT: Dal momento che C++ 11, è legale per utilizzare un tipo di locale come argomento di template.

risposta

50

È espressamente vietato dallo standard C++ 98/03.

C++ 11 rimuovere tale restrizione.

per essere più completo:

Le limitazioni sui tipi che sono utilizzato come parametri di modello sono elencati all'articolo 14.3.1 del C++ 03 (e C++ 98) norma:

un tipo locale, un tipo senza collegamento, un tipo o di un tipo anonimo aggravate da qualsiasi di questi tipi non devono essere utilizzati come argomento modello per un parametro di tipo di modello .

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 } 

Fonte e maggiori dettagli: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420

In sintesi, la restrizione è stata un errore che sarebbe stato fissato prima, se il principio è stato evolvendo più velocemente ...

che ha detto oggi la maggior parte delle ultime versioni di compilatori comuni lo consente, oltre a fornire espressioni lambda.

+0

Lo so, ma mi piacerebbe sapere dove vedere se riesco a capire perché. Hai un riferimento nello standard? –

+0

Ti riferisci a 14.3.1.2, "argomenti del tipo di modello"? – greyfade

+0

Ho aggiunto alcune informazioni e un link che potrebbe aiutare. Per riassumere, la restrizione era un errore che sarebbe stato risolto rapidamente se lo standard si stava evolvendo più velocemente ... – Klaim

5

La restrizione verrà rimossa in "0x", ma non penso che le userete molto. E questo perché C++ - 0x avrà lambda! :)

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

La mia sintassi sopra può non essere perfetta, ma l'idea generale è lì.

+0

Sapevo di lambda. In effetti, ciò che volevo ottenere è il più vicino possibile con lo standard attuale. Una specie di soluzione proposta da Java. –

+0

E in che modo si tratta di una risposta alla domanda reale (per non parlare di un valore di 4 voti positivi)? –

+0

@ChristianRau:;) Capisco perché lo diresti. La domanda è perché non sono ammessi e la prima riga della risposta risponde a questa domanda. è stato rimosso quindi non ci deve essere stata una buona ragione per la restrizione. All'epoca ho chiaramente pensato che i lambda fossero degni di nota. Ora, naturalmente, 3 anni dopo, i lambda sono ben noti, quindi non sono più notizie! –

Problemi correlati