Почему `this` является зависимым от типа выражением, даже если класс шаблона не имеет базового класса?

Следующий код может быть скомпилирован без ошибок:

template <typename T> struct A {
void f() { this->whatever; } // whatever is not declared before
};
int main() {
A<int> a;
}

И я знаю, что это потому, что this является зависимым от типа выражением, которое делает поиск имени для whatever откладывается до тех пор, пока фактический аргумент шаблона не станет известен. Так как функция-член f() никогда не используется в этом случае, так что нет A<T>::f существует, и поиск имени для whatever никогда не выполняется.

я могу понять, что this зависит от типа, если шаблон класса имеет основанную на типе базу, такую ​​как:

template <typename T> struct B { T whatever; };
template <typename T> struct A : B<T> {
void f() { this->whatever; }
};
int main() {
A<int> a;
}

При разборе определения класса шаблона Aневозможно узнать, какой тип его базы, что делает this->whatever потенциально законный (B<T> может иметь член по имени whatever). Наоборот, я не вижу потенциала, который this->whatever будет законным в первом примере, как только функция-член f используется где-то.

Итак, мог this->whatever быть легальным в некоторых моментах в первом примере? Если нет, есть ли другая причина, this в этом случае следует рассматривать как зависимое от типа выражение?

11

Решение

Ваш код «неправильно сформирован, диагностика не требуется», потому что никогда не существует действительной специализации для A::f, На самом деле, спецификация говорит, что this->whatever не является ни членом неизвестной специализации (потому что не существует зависимого базового класса), ни членом текущего экземпляра (потому что он не объявлен ни в независимом базовом классе, ни в самом шаблоне класса). Кроме того, это делает ваш код недействительным, и опять-таки никакая диагностика не требуется (но разрешена). Это объясняется более подробно на https://stackoverflow.com/a/17579889/34509

this зависит от типа, потому что вы еще не знаете значений параметров шаблона в определении. Так, например, SomeOtherTemplate<decltype(*this)> не может быть решена немедленно, но нужно подождать, пока шаблон класса this создается (так что вам нужно typename до SomeOtherTemplate<decltype(*this)>::type).

Однако только потому, что this зависит от типа, не означает, что this->whatever это также. Как описано выше, в спецификации есть инструменты, позволяющие правильно классифицировать это как недопустимое, и фактически не делать this->whatever зависит от типа. Это говорит

Выражение доступа к члену класса ([expr.ref]) зависит от типа, если выражение ссылается на член текущего экземпляра и тип ссылочного члена является зависимым, или выражение доступа к члену класса относится к члену неизвестного специализация.

4

Другие решения

Ваш пример может быть упрощен еще больше:

template <typename T> struct A {
void f() { this = 1; }
};
int main() {
A<int> a;
}

Заявление this = 1; никогда не должен компилироваться, и это не может быть исправлено, даже если A<T> имеет зависящий от типа базовый класс. Однако компилятор не жалуется, пока функция A<T>::f() создается экземпляр.

Как Йоханнес Шауб — Литб имеет уже ответил это может быть ситуация «не требует диагностики».

0

Это правила поиска имен зависимых имен.

$ 14,6 / 9 Разрешение имени
[temp.res]
:

При поиске объявления имени, используемого в определении шаблона, для независимых имен используются обычные правила поиска ([basic.lookup.unqual], [basic.lookup.argdep]). Поиск имен, зависящих от параметров шаблона, откладывается до тех пор, пока фактический аргумент шаблона не станет известен ([temp.dep]).

Намерение состоит в том, что информации недостаточно, если имя зависит от параметра шаблона, пока фактический аргумент шаблона не известен. Компилятор не различает тип зависимых имен (формируется this или другие), не будет проверять детали, как класс имеет зависимый базовый класс или нет. Результат может не измениться, как пример кода, который вы показали, но он просто откладывает поиск имени, пока тип не станет известен, чтобы принять наиболее точное решение.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector