Семантическая корректность неинстанцированных шаблонных функций C++

Следующий код C++ не компилируется, например, с g++-4.7 или clang++-3.2:

struct Bar {};

template<typename T>
void foo(T t, Bar bar) {
    t.compiler_does_not_care();
    bar.nonexistent_method();
}

int main() {}

Почему компиляторы проверяют код функции-шаблона foo на семантическую корректность (где они могут), даже если он никогда не создается? Соответствует ли этот стандарт?

1 ответ

Решение

Bar является независимым именем (т.е. его тип не зависит от T), поэтому компилятор должен проверять правильность кода на первом этапе поиска по имени (см. примечание ниже).

поскольку Bar не имеет nonexistent_method() Метод, компилятор должен поставить диагноз.

Если вы измените свой шаблон на:

template<typename T>
void foo(T t, T bar) {
    t.compiler_does_not_care();
    bar.nonexistent_method();
}

Никакие независимые имена не участвуют, поэтому ошибка не генерируется, так как шаблон никогда не создается (фаза 2 поиска)


Заметки:

  • Приемлемое описание поиска двухфазного имени из LLVM:

1) Время определения шаблона: при первоначальном анализе шаблона задолго до его создания компилятор анализирует шаблон и ищет любые "независимые" имена. Имя является "независимым", если результаты поиска имени не зависят от каких-либо параметров шаблона и, следовательно, будут одинаковыми от одного экземпляра шаблона к другому.

2) Время создания шаблона: когда создается экземпляр шаблона, компилятор ищет любые "зависимые" имена, теперь, когда у него есть полный набор аргументов шаблона для выполнения поиска. Результаты этого поиска могут (и часто делают!) Варьироваться от одного экземпляра шаблона к другому.

  • Что касается того, почему поиск независимого имени не может быть отложен до второй стадии, см. Этот другой пост SO; кажется, что это в основном по историческим причинам.
Другие вопросы по тегам