Функция члена шаблона класса шаблона, вызванная из функции шаблона
Это не скомпилируется:
template<class X> struct A {
template<int I> void f() {}
};
template<class T> void g()
{
A<T> a;
a.f<3>(); // Compilation fails here (Line 18)
}
int main(int argc, char *argv[])
{
g<int>(); // Line 23
}
В компиляторе (gcc) говорится:
hhh.cpp: В функции 'void g()':
hhh.cpp: 18: ошибка: ожидаемое первичное выражение перед ')' токеном
hhh.cpp: В функции 'void g() [с T = int]':
hhh.cpp: 23: экземпляр здесь
hhh.cpp: 18: ошибка: недопустимое использование члена (вы забыли "&"?)
Может кто-нибудь объяснить, почему это? Есть ли способ заставить его работать?
Ответы
Ответ 1
Попробуйте использовать следующий код:
template<class T> void g()
{
A<T> a;
a.template f<3>(); // add `template` keyword here
}
Согласно С++ '03 Standard 14.2/4:
Когда имя специализированного шаблона шаблона появляется после .
или ->
в постфиксном выражении или после вложенного имени-спецификатора в идентификаторе с квалифицированным идентификатором, а постфиксное выражение или квалифицированный идентификатор явно зависит по шаблону-параметру (14.6.2), имя шаблона члена должно иметь префикс с ключевым словом template
. В противном случае предполагается, что имя называется не-шаблоном.
Будущему стандарту С++ по-прежнему требуется это ключевое слово согласно проекту n2857 14.3/4. Некоторые компиляторы имеют специальный режим, который позволяет скомпилировать исходный код без ошибок (Комо компилирует его в так называемом расслабленном режиме).
Ответ 2
Где определяется тип T?
Когда вы вызываете функцию g() в это время, тип T должен быть известен еще, готовьтесь к ошибке компилятора, говоря, что T undefined.
Ответ 3
Не могли бы вы указать, какой компилятор вы используете? Код в вопросе, с
int main() {
g<int>();
}
добавлен скомпилированный без проблем с помощью cl.exe из Microsoft Visual Studio 9;
Не удалось выполнить различные версии g++, которые я пробовал, и онлайн-компилятор Comeau.