2017-06-07 7 views
26

Ce code compile avec MSVC 2015, mais ne compilent pas avec Clang 5.0.0 (tronc 304874):Est-ce obligatoire pour accéder aux identifiants Base <T> des classes dérivées?

template <typename T> 
struct Base 
{ 
    T data; 
}; 

template <typename T> 
struct Derived : Base<T> 
{ 
    auto getData() const 
    { 
    return data; 
    } 
}; 

Remplacement data avec this->data dans Derived::getdata() rend Clang heureux.

Quel compilateur est correct selon la norme C++?

Doit-on utiliser le code this-> pour accéder à un identificateur d'une classe de base?

+1

msvc est faux, évidemment. 'data' est un nom dépendant. –

+0

clang est correct, msvc est faux. –

+2

MSVC est rompu en ce qui concerne les règles de recherche en deux phases, qui incluent des noms dépendants. – Quentin

Répondre

27

Clang est correct.

$17.6.2/3 Dependent names [temp.dep]

Dans la définition d'un modèle de classe ou de classe, le champ d'application n'est pas examiné une classe de base dépendante lors de la recherche de nom non qualifié, soit au moment de la définition du modèle de classe ou d'un membre ou au cours d'une instanciation du modèle de classe ou du membre.

Pour return data;, data est non qualifiée, puis la recherche de nom non qualifié sera employé. Cela signifie que le nom dans la classe de base Base<T> (qui est une classe de base dépendante car il dépend du paramètre de modèle T) ne devrait pas être trouvé; c'est-à-dire que les noms non dépendants ne sont pas recherchés dans les classes de base dépendantes.

this->data ou Base<T>::data le rend qualifié. Cela signifie que le nom sera recherché au moment de l'instanciation, et à ce moment la spécialisation de base exacte qui doit être explorée sera connue.

+2

'this-> data' n'est pas un nom qualifié. –

+1

Toujours faux."nom qualifié" et "nom dépendant" ne sont pas interchangeables. En fait, ils sont mutuellement exclusifs. –

+0

@ T.C. Je suis confus; donc je ne peux pas dire 'name' est un nom non-dépendant ou' this-> data' est un nom dépendant? Alors quelle devrait être la description correcte de ces noms? Ou je peux seulement dire qu'ils sont «qualifiés» ou «non qualifiés»? (mais pas "nom qualifié" etc?) S'il vous plaît dites-moi si je me trompe à la base de la réponse, ou est-ce un problème de terme? – songyuanyao

15

Oui, c'est. Fondamentalement data dépend de T.

Il existe un mécanisme appelé recherche en deux phases. Les noms dépendants non (modèle) sont résolus immédiatement - au point définition. Votre data n'existe pas encore, car Base<T> n'existe pas encore, car il n'a pas été instancié. Ainsi, il se plaint que data est introuvable.

Vous devez indiquer au compilateur que data dépend du modèle et que la recherche de nom doit être effectuée dans la deuxième phase, une fois les paramètres de modèle remplacés, c'est-à-dire que la classe de modèle a été instanciée. Cela peut être fait en utilisant this ou en fournissant une portée dépendant du modèle. Par conséquent, this->f() ou Base<T>::f() fonctionneront.