¿Cómo entiendes los nombres dependientes en C ++?

Me encuentro con el término “nombres dependientes” típicamente en el contexto de las plantillas. Sin embargo, rara vez toco esto último. Por lo tanto, naturalmente, me gustaría saber más sobre el concepto de nombres dependientes.

¿Cómo lo entiendes en el contexto de las plantillas y fuera de ellas? ejemplo son críticamente alentados!

Un nombre dependiente es esencialmente un nombre que depende de un argumento de plantilla.

Al usar plantillas, hay una distinción entre el punto de definición de la plantilla y el punto de creación de instancias, es decir, donde realmente usa la plantilla. Los nombres que dependen de una plantilla no se enlazan hasta el punto de instanciación, mientras que los nombres que no se enlazan en el punto de definición.

Un ejemplo simple sería:

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

donde una statement o definición de i tendría que aparecer antes de la definición dada anteriormente ya que no depende del argumento de la plantilla T y, por lo tanto, está obligado en el punto de definición. La definición del miembro toInt de la variable x tipo-aún-desconocido solo tiene que aparecer antes de que la función addInt se use realmente en alguna parte ya que es un nombre dependiente (técnicamente el punto de instanciación se toma como el espacio global o de espacio adjunto más cercano) scope justo antes del punto de uso, por lo que debe estar disponible antes de eso).

Los nombres dependientes se caracterizan por una dependencia en un argumento de plantilla. Ejemplo trivial:

 #include  void NonDependent() { //You can access the member size_type directly. //This is precisely specified as a vector of ints. typedef std::vector IntVector; IntVector::size_type i; /* ... */ } template  void Dependent() { //Now the vector depends on the type T. //Need to use typename to access a dependent name. typedef std::vector SomeVector; typename SomeVector::size_type i; /* ... */ } int main() { NonDependent(); Dependent(); return 0; } 

EDITAR : Como mencioné en el comentario a continuación, este es un ejemplo de una situación peculiar con respecto al uso de nombres dependientes que aparece con bastante frecuencia. A veces, las reglas que rigen el uso de nombres dependientes no son lo que uno podría esperar instintivamente.

Por ejemplo, si tiene una clase dependiente que se deriva de una base dependiente, pero dentro de un scope en el que un nombre de la clase base aparentemente no depende de la plantilla, puede obtener un error de comstackción como el siguiente.

 #include  template  class Dependent { protected: T data; }; template  class OtherDependent : public Dependent { public: void printT()const { std::cout < < "T: " << data << std::endl; //ERROR } }; int main() { OtherDependent o; o.printT(); return 0; } 

Este error ocurre porque el comstackdor no buscará el name dentro de la plantilla de la clase base, ya que no depende de T y, por lo tanto, no es un nombre dependiente. Las formas de corregir están usando this o diciendo explícitamente la plantilla de clase base dependiente:

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