2010-09-07 6 views

Répondre

4

Si vous n'utilisez pas l'argument par défaut (c'est-à-dire que vous fournissez une valeur), il n'est pas du tout instancié.

14.7.1/2:

moins une spécialisation de modèle de fonction a été explicitement instancié ou explicitement spécialisés, le modèle de fonction spécialisation est implicitement instanciée lorsque la spécialisation est référencé dans un contexte qui nécessite une définition de fonction à existe. À moins qu'un appel à une fonction modèle spécialisation explicite ou une fonction de membre d'un explicitement modèle de classe spécialisée, un argument par défaut pour un modèle de fonction ou une fonction membre d'un modèle de classe est instanciée implicitement lorsque la fonction est appelé dans un contexte qui requiert la valeur de l'argument par défaut .

Quelle bouchée. En fait, les arguments par défaut des fonctions et des modèles ont des règles d'instanciation spécifiques à eux-mêmes.

+1

la question est 'A (C c = C())' où 'C :: C()' n'a pas de valeur par défaut – Anycorn

+0

@aaa: Oh, désolé. Si vous n'utilisez pas l'argument par défaut, il n'est pas évalué. – Potatoswatter

3

Je ne suis pas sûr de savoir quel est votre dilemme. Si vous vous demandez comment le modèle peut être instancié lorsqu'il n'y a pas de constructeur par défaut, c'est bien. Le premier argument par défaut du constructeur de modèle est uniquement requis si aucun argument n'est fourni. Le compilateur est heureux avec C n'ayant pas un constructeur par défaut car il n'a pas besoin de l'utiliser.

D'autre part, si vous avez essayé

A<C> a; 

Le compilateur devrait correspondre à l'appel du constructeur à A<C>::A(C) avec l'argument par défaut C(), et qui déclenchera une erreur de compilation que le type C ne le fait pas avoir un constructeur par défaut.

La citation réelle de la norme est de §14.7.1 [temp.inst]/11:

Si un modèle de fonction f est appelé d'une manière qui nécessite une expression d'argument par défaut à utiliser, les noms dépendants sont recherchés, les contraintes sémantiques sont vérifiées et l'instanciation de tout modèle utilisé dans l'expression par défaut est faite comme si l'expression par défaut avait été une expression utilisée dans une spécialisation de modèle de fonction avec la même portée, la même paramètres de modèle et le même accès que celui du modèle de fonction f utilisé à ce moment-là. Cette analyse est appelée instanciation d'argument par défaut. L'argument par défaut instancié est ensuite utilisé comme argument de f.

Il existe un exemple réel dans le paragraphe suivant §14.7.1 [temp.inst]/12:

Chaque argument par défaut est instancié indépendamment. [Exemple:

template<class T> 
void f(T x, T y = ydef(T()), T z = zdef(T())); 
class A { }; 
A zdef(A); 
void g(A a, A b, A c) { 
    f(a, b, c);   // no default argument instantiation 
    f(a, b);   // default argument z = zdef(T()) instantiated 
    f(a);    // ill-formed; ydef is not declared 
} 

-end exemple]

3

Si l'argument par défaut est jamais utilisé, cela est bien beau, comme jamais réellement évalué par le compilateur jusqu'à ce qu'il soit utilisé. Cependant, dès que vous utilisez l'argument par défaut tel que:

A<C> a; 

vous devriez obtenir une erreur de compilation.

Questions connexes