2010-07-19 2 views
1

J'ai essayé de travailler avec des templates depuis un moment maintenant et plus j'en fais moins, je réalise que je comprends. Ce dernier problème semble avoir mis au jour un malentendu plutôt fondamental de ma part et je commence à penser plus que jamais: "Bon, demain je ne devrais pas écrire de code mais plutôt trouver une bibliothèque avec une bonne section CS et juste lis tout ce qu'ils ont sur les gabarits "! Je me demande si, en attendant, vous pouvez m'aider.Différences entre un template paramétré `typename` et un type intégral Un

Ainsi, le code suivant,

template <typename T> // or replace `typename` with `class` 
struct Foo { 
    struct Bar {}; 
    Foo(Bar) {} 
}; 

Foo<float>::Bar x; 
Foo<int> y (x); 

ne compile pas depuis x est de type Foo<float>::Bar mais pour construire y nous avons besoin d'un Foo<int>::Bar. Très bien, et prévu, mais maintenant considérer ce qui suit,

template <int I> 
struct Foo { 
    struct Bar {}; 
    Foo(Bar) {} 
}; 

Foo<0>::Bar x; 
Foo<1> y (x); 

J'espérais/pense (même si, heureusement, pas encore compter sur) que x serait de type Foo<0>::Bar et de construire y nous aurions besoin d'un Foo<1>::Bar et en tant que tel, il ne compilerait pas - comme dans l'exemple précédent. Mais il semble que les deux sont en fait de type Foo<int>::Bar et ainsi, ce va compiler. Donc, je me demande d'abord quelle est la terminologie correcte pour décrire cette différence entre un template paramétré de type typename/class et un template paramétré de type integral, quelles autres différences de comportement cela implique-t-il, et quelle méthode pourrais-je utiliser? utiliser pour résoudre ce problème et obtenir le comportement souhaité pour cet exemple simple afin que Foo<0> et Foo<1> décrivent les types incompatibles? Et, avant ce voyage à la bibliothèque, tout lien vers des documents de lecture «essentiels», en ligne, sur le sujet serait également le bienvenu. Merci.

+2

Votre dernier exemple ne compile pas sur GCC. Quel compilateur utilisez-vous? – Yuji

+2

Le code que vous donnez certainement ne devrait pas compiler, pour exactement la raison que vous donnez: 'Foo <0>' et 'Foo <1>' sont des types distincts. Quel compilateur utilisez-vous? –

+0

Et prendre cette liste à la bibliothèque avec vous: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list –

Répondre

2

Sur gcc 4.4.3 votre deuxième exemple ne peut pas compiler avec le message "erreur: aucune fonction de mise en correspondance pour l'appel à 'Foo < 1> :: Foo (Foo < 0> :: Bar &)", qui est exactement ce que vous attendiez.

Donc, vous n'avez rien mal compris. Si cela compile pour vous, c'est un comportement non-standard de votre compilateur.

Questions connexes