Подтвердить что ты не робот

Является ли this-> обязательным для доступа к базовым <T> идентификаторам из производных классов?

Этот код компилируется с MSVC 2015, но не компилируется с Clang 5.0.0 (trunk 304874):

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

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

Замена data на this->data в Derived::getdata() делает Кланг счастливым.

Какой компилятор корректен в соответствии со стандартом С++?

Должен this-> использоваться в шаблоне для доступа к идентификатору базового класса?

4b9b3361

Ответ 1

Правильно. Clang.

$17.6.2/3 Зависимые имена [temp.dep]

В определении шаблона класса или класса область зависимого базового класса не рассматривается во время поиска неквалифицированного имени либо в точке определения шаблона класса или члена, либо во время создания шаблона или члена класса.

Для return data;, data является неквалифицированным, тогда будет использоваться неквалифицированный поиск имени. Это означает, что имя в базовом классе Base<T> (которое является зависимым базовым классом, поскольку оно зависит от параметра шаблона T) не должно быть найдено; то есть независящие имена не просматриваются в зависимых базовых классах.

this->data или Base<T>::data делает его квалифицированным. Это означает, что имя будет рассмотрено во время создания экземпляра, и в то время будет известна точная базовая специализация, которая должна быть исследована.

Ответ 2

Да, это так. В основном data зависит от T.

Существует механизм, называемый двухфазным поиском. Имена без имени (шаблона) разрешаются немедленно - в точке определения. Ваш data еще не существует, потому что Base<T> еще не существует, поскольку он не был создан. Таким образом, он жалуется, что data не найден.

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

Таким образом, будут работать либо this->f(), либо Base<T>::f().