Шаблоны: функция шаблона не очень хорошо работает с функцией-членом класса

Это минимальный тестовый пример кода, который у меня есть на самом деле. Это не удается, когда он пытается оценить 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>();

Другие вопросы по тегам