Когда зависимое имя используется для ссылки на вложенный шаблон, вложенное имя должно быть добавлено к ключевому слову template
, чтобы помочь компилятору поймите, что вы имеете в виду вложенный шаблон, и правильно проанализируйте код
template <typename T>
void F(A<T> &a)
{
a.template f<0>();
}
Внутри main
имя a
не зависит, поэтому вам не нужен дополнительный ] ключевое слово
шаблона. Внутри F
name a
зависит, поэтому ключевое слово необходимо.
Это похоже на дополнительное ключевое слово typename
при обращении к именам вложенных типов через зависимое имя. Просто синтаксис немного другой.
В первом случае компилятор думает, что вы имеете в виду ...
a.f < 0 ...gibberish....
Ответ Андрея исправляет это.
Обратите внимание, что есть фрагменты кода , которые действительны для как добавленного ключевого слова, так и не добавленного, что дает разные результаты в каждом случае, даже для шаблонов, которые принимать параметры типа вместо целых чисел.
#include <iostream>
struct A {
template<typename T>
static A f(T) {
return A();
}
template<typename T> operator T() { return T(); }
};
template<typename U>
int g() {
U u;
typedef A (*funcPtrType)(int());
return !(funcPtrType)u.f < int() > (0);
}
int main() {
std::cout << g<A>() << std::endl;
}
Это выводит 0
при запуске без добавления ключевого слова шаблона
. Если вы добавите ключевое слово перед f
, оно выведет 1
.
Объяснение
Версия без ключевого слова анализируется как
funcPtrType temp1 = (funcPtrType)u.f; // taking func address
bool temp2 = !temp1; // temp2 == false
bool temp3 = temp2 < int(); // temp3 == false
bool temp4 = temp3 > (0); // temp4 == false
return temp4;
И версия с ключевым словом анализируется как
A temp1 = u.template f < int() > (0); // function call
funcPtrType temp2 = (funcPtrType) temp1; // temp2 == 0
bool temp3 = !temp2; // temp3 == true
return temp3;
Обратите внимание, что temp2
является пустым указателем (создается return T ( )
). Совершенно разные синтаксические разборы, и оба действительны! Это действительно нуждается в способе устранения неоднозначности, который заключается в вставке соответствующего ключевого слова template
.