Использование неполного типа в функции-члене шаблона класса - PullRequest
7 голосов
/ 07 мая 2019

GCC (8.3, 9.1), Clang (7, 8) и MSVC (19.20) отличаются своей способностью компилировать этот код:

struct C;

template<typename T> struct S {
    void foo() {
        // C2 c;
        C c;
    }
};

class C {};

int main() {
    S<int> s;
    s.foo();
    return 0;
}

GCC и MSVC принимают его, а Clang отвергает. Clang отклоняет его, даже если я сам создаю шаблон foo и / или не вызываю его вообще.

Насколько я понимаю, foo не создается, если он не вызывается, и создается в точке, где он вызывается. На этом этапе C завершено, и код должен скомпилироваться. Это обоснование GCC?

В качестве примечания, если foo не вызывается, MSVC принимает код, даже если я заменяю C на необъявленный C2 внутри foo - в этом случае, кажется, просто проверяется тело функции на быть синтаксически правильным.

Какое поведение является правильным в соответствии со Стандартом? Если это Clang, почему Стандарт запрещает гибкость, которую дает GCC?

1 Ответ

12 голосов
/ 07 мая 2019

Это плохо сформировано, диагностика не требуется, из-за [temp.res] / 8 :

Программа некорректна, диагностика не требуется, если:

  • [...]
  • гипотетическая реализация шаблона сразу после его определения будет некорректной из-за конструкции, которая не зависит от параметра шаблона, или [...]
  • [...]

Итак, вся программа плохая, но реализации не требуется для ее диагностики. Clang делает, что хорошо для clang, gcc и MSVC, что не так.

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