2009-04-12 5 views
48

Je me suis toujours demandé pourquoi vous ne pouvez pas utiliser les classes définies localement comme prédicats aux algorithmes STL.Utilisation de classes locales avec des algorithmes STL

Dans la question suivante: Approaching STL algorithms, lambda, local classes and other approaches, BubbaT mentionne dit que 'Depuis le standard C++ interdit les types locaux à utiliser comme arguments'

Exemple Code:

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 
} 

Est-ce que quelqu'un sait où dans le la norme est la restriction? Quelle est la raison d'interdire les types locaux?


EDIT: Depuis C++ 11, il est légal d'utiliser un type local comme un argument de modèle.

Répondre

50

Il est explicitement interdit par la norme C++ 98/03.

C++ 11 supprime cette restriction.

Pour être plus complet:

Les restrictions sur les types qui sont utilisés comme paramètres de modèle sont répertoriés à l'article 14.3.1 du 03 C++ (C++ et 98) standard:

un type local, un type sans lien, un type sans nom ou un type de aggravé l'un de ces types ne doivent pas être utilisés en tant qu'argument de modèle pour un paramètre de type de modèle .

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 } 

Source et plus de détails: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420

En résumé, la restriction était une erreur qui aurait été fixé plus tôt si la norme évoluait plus vite ...

Cela dit aujourd'hui la plupart des dernières versions de compilateurs communs le permettent, tout en fournissant des expressions lambda.

+0

Je sais, mais j'aimerais savoir où je peux comprendre pourquoi. Avez-vous une référence dans la norme? –

+0

Faites-vous référence à 14.3.1.2, "arguments de type template"? – greyfade

+0

J'ai ajouté quelques informations et un lien qui pourrait aider. En résumé, la restriction était une erreur qui aurait été corrigée rapidement si la norme évoluait plus vite ... – Klaim

5

La restriction sera supprimée dans '0x, mais je ne pense pas que vous les utiliserez beaucoup. Et c'est parce que C++ - 0x va avoir des lambdas! :)

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

Ma syntaxe dans ce qui précède peut ne pas être parfaite, mais l'idée générale est là.

+0

Je connaissais lambdas. En fait, ce que je voulais atteindre était le plus proche possible de la norme actuelle. Genre de la solution proposée par Java. –

+0

Et de quelle manière est-ce une réponse à la question actuelle (et encore moins une question vaut 4 votes)? –

+0

@ ChristianRau:;) Je peux voir pourquoi vous diriez ceci. La question est de savoir pourquoi ils ne sont pas autorisés et la première ligne de la réponse répond à cette question. il a été retiré, donc il ne doit pas y avoir de bonne raison pour la restriction. À l'époque, je pensais clairement que les lambdas valaient la peine d'être mentionnés. Maintenant, bien sûr, 3 ans plus tard, les lambdas sont bien connus et ne sont plus des nouvelles! –

Questions connexes