Question Comment comprenez-vous les noms dépendants en C ++


Je rencontre ce terme "noms dépendants" généralement dans le contexte de modèles. Cependant, je touche rarement ce dernier. Donc, naturellement, vous voudriez en savoir plus sur le concept de noms dépendants.

Comment le comprenez-vous dans le contexte des modèles et en dehors d'eux? exemple sont vivement encouragés!


12
2017-10-06 20:12


origine


Réponses:


Un nom dépendant est essentiellement un nom qui dépend d'un argument de modèle.

Lors de l'utilisation de modèles, il existe une distinction entre le point de définition du modèle et le point d'instanciation, c'est-à-dire où vous utilisez réellement le modèle. Les noms qui dépendent d'un modèle ne sont liés qu'au moment de l'instanciation, alors que les noms qui ne sont pas liés au point de définition.

Un exemple simple serait:

template< class T > int addInt( T x )
{
    return i + x.toInt();
}

lorsqu'une déclaration ou une définition de i devrait apparaître avant la définition donnée ci-dessus depuis i ne dépend pas de l'argument de modèle T et est donc lié au point de définition. La définition du toInt membre du type encore inconnu x la variable doit seulement apparaître avant le addInt function est en fait utilisée quelque part car c'est un nom dépendant (techniquement, le point d'instanciation est pris comme la portée globale ou d'espace de noms la plus proche juste avant le point d'utilisation et doit donc être disponible avant).


10
2017-10-06 20:23



Les noms dépendants sont caractérisés par un dépendance sur un argument de modèle. Exemple trivial:


#include <vector>

void NonDependent()
{
  //You can access the member size_type directly.
  //This is precisely specified as a vector of ints.

  typedef std::vector<int> IntVector;  
  IntVector::size_type i;

  /* ... */
}

template <class T>
void Dependent()
{

  //Now the vector depends on the type T. 
  //Need to use typename to access a dependent name.

  typedef std::vector<T> SomeVector;
  typename SomeVector::size_type i;

  /* ... */
}

int main()
{
  NonDependent();
  Dependent<int>();
  return 0;
}

MODIFIER: Comme je l'ai mentionné dans le commentaire ci-dessous, il s'agit d'un exemple d'une situation particulière concernant l'utilisation de noms dépendants qui apparaît assez fréquemment. Parfois, les règles régissant l'utilisation de noms dépendants ne sont pas ce à quoi on peut s'attendre instinctivement.

Par exemple, si vous avez une classe dépendante qui dérive d'une base depenent, mais dans une portée dans laquelle un nom de la classe de base ne dépend apparemment pas du modèle, vous pourriez obtenir une erreur de compilation comme ci-dessous.


#include <iostream>

template <class T>
class Dependent
{
protected:
  T data;
};

template <class T>
class OtherDependent : public Dependent<T>
{
public:
  void printT()const
  { 
    std::cout << "T: " << data << std::endl; //ERROR
  }
};

int main()
{
  OtherDependent<int> o;
  o.printT();
  return 0;
}


Cette erreur se produit car le compilateur ne va pas chercher name à l'intérieur du modèle de classe de base car il ne dépend pas de T et, par conséquent, ce n'est pas un nom de personne à charge. Les moyens de corriger utilisent this ou indiquer explicitement le modèle de classe de base dépendant:


std::cout << "T: " << this->data << std::endl; //Ok now.
std::cout << "T: " << Dependent<T>::data << std::endl; //Ok now.


8
2017-10-06 20:44