Почему зависимое имя может считаться полным, даже если фактический тип не определен до самого конца? - PullRequest
0 голосов
/ 18 сентября 2018

Рассмотрим этот пример :

template <class T>
void Yeap(T);

int main() {
    Yeap(0);
    return 0;
}

template <class T>
void YeapImpl();

struct X;

template <class T>
void Yeap(T) {
    YeapImpl<X>(); // pass X to another template
}

template <class T>
void YeapImpl() {
    T().foo();
}

struct X {
    void foo() {}
};

Обратите внимание, что struct X не определено до самого конца.Раньше я считал, что все используемые в odr имена должны быть полными в момент создания экземпляра.Но здесь, как компилятор может обработать его как полный тип до его определения?

Я проверил правила привязки и правила поиска для экземпляра зависимого имени и шаблона функции в cppreference, но ни один из них не может объяснить, чтоздесь происходит.

1 Ответ

0 голосов
/ 18 сентября 2018

Я считаю, что эта программа некорректна, диагностика не требуется.

[temp.point] / 8 читает, редактируя ненужные части:

Специализация для шаблона функции [...] может иметь несколько точек создания экземпляров в единице перевода и, в дополнение к описанным выше точкам создания экземпляров, для любой такой специализации, которая имеет точку создания в единице перевода,конец единицы перевода также считается точкой создания экземпляра.[...] Если две разные точки инстанцирования придают специализации шаблона разные значения в соответствии с правилом единого определения, программа некорректна, диагностика не требуется.

YeapImpl<X> имеет дваточки инстанцирования: где он вызывается в строке комментария в вопросе и в конце блока перевода.В первом пункте реализации, X является неполным, что сделало бы тело функции плохо сформированным.Во втором пункте реализации, X завершена, что делает тело хорошо сформированным.

Эти две специализации имеют [очень] разные значения.

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