Шаблоны: функция шаблона не очень хорошо работает с функцией-членом класса
Это минимальный тестовый пример кода, который у меня есть на самом деле. Это не удается, когда он пытается оценить a.getResult<B>()
:
test.cpp: In function 'void printStuff(const A&)':
test.cpp:6: error: expected primary-expression before '>' token
test.cpp:6: error: expected primary-expression before ')' token
Код является:
#include <iostream>
template< class A, class B>
void printStuff( const A& a)
{
size_t value = a.getResult<B>();
std::cout << value << std::endl;
}
struct Firstclass {
template< class X >
size_t getResult() const {
X someInstance;
return sizeof(someInstance);
}
};
int main(int, char**) {
Firstclass foo;
printStuff<Firstclass, short int>(foo);
printStuff<Firstclass, double>(foo);
std::cout << foo.getResult< double >() << std::endl;
return 0;
}
Если я закомментирую printStuff
функция и где она называется, foo.getResult< double >()
вызов компилируется нормально и делает то, что ожидается.
Есть идеи, что происходит? Некоторое время я работал с сильно шаблонным кодом и никогда не сталкивался с чем-то подобным.
2 ответа
Когда вы ссылаетесь на шаблон, который является членом зависимого типа, вы должны добавить к нему ключевое слово template
, Вот как зов к getResult
внутри printStuff
должен выглядеть
size_t value = a.template getResult<B>();
Это похоже на использование ключевого слова typename
при обращении к вложенным типам в зависимом типе. По какой-то причине немного о typename
с вложенными типами довольно хорошо известны, но аналогичное требование для template
с вложенными шаблонами относительно неизвестно.
Обратите внимание, что общая структура синтаксиса немного отличается. typename
всегда ставится перед полным именем типа, в то время как template
вставляется в середине.
Опять же, это необходимо только при доступе к элементу шаблона зависимого типа, который в приведенном выше примере будет A
в printStuff
, Когда вы звоните foo.getResult<>
в main
тип foo
не зависит, поэтому нет необходимости включать template
ключевое слово.
Ваш код некорректен в соответствии со стандартом C++ 14.2/4:
Когда имя специалиста шаблона члена появляется после
.
или же->
в выражении postfix или после спецификатора вложенного имени в квалифицированном идентификаторе, а выражение postfix или уточненный идентификатор явно зависит от параметра шаблона (14.6.2), перед именем шаблона элемента должен стоять префикс ключевое словоtemplate
, В противном случае предполагается, что имя не является шаблоном.
Итак, вы должны написать size_t value = a.template getResult<B>();