Семантическая корректность неинстанцированных шаблонных функций 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; кажется, что это в основном по историческим причинам.