Шаблоны: Разрешение имен -> может ли кто-нибудь рассказать другой пример для этого утверждения ... пожалуйста - PullRequest
0 голосов
/ 20 сентября 2010

Это заявление стандарта ISO C ++ 14.6 / 8:

При поиске объявления имени, используемого в определении шаблона, обычные правила поиска используются для независимых имен. Поиск имен, зависящих от параметров шаблона, откладывается до тех пор, пока фактический аргумент шаблона не станет известен (14.6.2).

Пример:

  #include <iostream>
  using namespace std;
  template<class T> class Set {
            T* p;
            int cnt;
  public:
            Set();
            Set<T>(const Set<T>&);
            void printall()
            {
                        for (int i = 0; i<cnt; i++)
                                   cout << p[i] << ’\n’;
            }
            // ...
  };

в примере, i - это локальная переменная, объявленная в printall, cnt - член cnt, объявленный в Set, а cout - стандартный поток вывода, объявленный в iostream. Однако не каждое объявление может быть найдено таким образом; разрешение некоторых имен должно быть отложено до тех пор, пока фактические аргументы шаблона не станут известны. Например, хотя имя оператора << известно в определении printall () и его объявление можно найти, фактическое объявление оператора <<, необходимое для печати p [i], невозможно узнать, пока оно не станет известным что такое тип Т (14.6.2). </p>

Я не могу понять этот момент ... и пример тоже?

Может ли кто-нибудь рассказать другой пример для этого утверждения ... пожалуйста

Ответы [ 3 ]

2 голосов
/ 20 сентября 2010

Глядя только на шаблон, можете ли вы сказать мне, что тип p[i]?Нет. Тип p[i] в Set<int> будет int;тип p[i] в Set<std::string> будет std::string.Следовательно, поиск operator<< должен быть отложен до тех пор, пока не будет создан экземпляр шаблона и тип p[i] не известен.

У вас возникла бы похожая проблема в (предположим, что это другой член Set<T>)

// In Set<T>
void reverse()
{
  for (int i = 0; i <= cnt-i; ++i)
  {
    using std::swap;
    swap(p[i], p[cnt-i]);
  }
}

Для поиска подкачки также потребуется тип p[i], хотя непосредственно перед ним есть объявление использования.

0 голосов
/ 20 сентября 2010

Шаблоны имеют концепцию dependent name и non-dependent name. Проще говоря, это те имена, которые так или иначе зависят от параметра шаблона. В вашем коде 'T * p' делает 'p' зависимым именем, поскольку оно зависит от параметра шаблона T

Теперь cout << p[i] требуется перегрузка operator <<, вот так

ostream& operator << (ostream &os, T const &t);

или перегрузка operator <<, в которую можно преобразовать 'T'.

Но доступна ли такая перегрузка? Как компилятор узнает об этом до тех пор, пока не станет известен «T»?

Это именно то, о чем говорит приведенная выше цитата из Стандарта.

Имена, такие как 'i' и т. Д., Не зависят, поскольку они никак не зависят от параметра шаблона. Следовательно, поиск таких независимых имен может быть разрешен немедленно, даже если «Т» неизвестно

0 голосов
/ 20 сентября 2010
T* p;
...
for (int i = 0; i<cnt; i++)
    cout << p[i] << ’\n’;

в основном вы не знаете, является ли cout << p[i] << ’\n’; допустимым выражением (например), пока не узнаете тип T

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...