Как вы понимаете зависимые имена в C ++ - PullRequest
14 голосов
/ 07 октября 2009

Я сталкиваюсь с этим термином «зависимые имена», как правило, в контексте шаблонов. Однако я редко прикасаюсь к последнему. Поэтому, естественно, хотелось бы узнать больше о понятии зависимых имен.

Как вы понимаете это в контексте шаблонов и вне их? пример критически приветствуется!

Ответы [ 2 ]

11 голосов
/ 07 октября 2009

Зависимое имя - это имя, которое зависит от аргумента шаблона.

При использовании шаблонов существует различие между точкой определения шаблона и точкой создания экземпляра, то есть где вы фактически используете шаблон. Имена, которые зависят от шаблона, не связываются до момента создания экземпляра, тогда как имена, которые не связываются в момент определения.

Простой пример:

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

где объявление или определение i должно появиться до определения, данного выше, поскольку i не зависит от аргумента шаблона T и поэтому связано в точке определения , Определение toInt члена переменной пока еще неизвестного типа x должно появиться только до того, как функция addInt будет фактически где-то использоваться, так как это зависимое имя (технически точка создания принимается за ближайшая глобальная область или область имен, расположенная непосредственно перед точкой использования, поэтому она должна быть доступна до этого).

9 голосов
/ 07 октября 2009

Зависимые имена характеризуются зависимостью от аргумента шаблона. Тривиальный пример:


#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;
}

РЕДАКТИРОВАТЬ : Как я уже упоминал в комментарии ниже, это пример особой ситуации с использованием зависимых имен, которая встречается довольно часто. Иногда правила, регулирующие использование зависимых имен, не соответствуют ожиданиям инстинкта.

Например, если у вас есть зависимый класс, производный от зависимой базы, но внутри области, в которой имя базового класса явно не зависит от шаблона, вы можете получить ошибку компилятора, как показано ниже.


#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;
}


Эта ошибка возникает из-за того, что компилятор не будет искать name внутри шаблона базового класса, поскольку он не зависит от T и, следовательно, не является зависимым именем. Для исправления можно использовать this или явно указать шаблон зависимого базового класса:

<code>
std::cout << "T: " << this->data << std::endl; //Ok now.
std::cout << "T: " << Dependent<T>::data << std::endl; //Ok now.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...