模板:模板函数与类的模板成员函数不兼容

时间:2009-11-05 19:04:52

标签: c++ templates

这是我实际拥有的一些代码的最小测试用例。它在尝试评估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 个答案:

答案 0 :(得分:39)

当您引用属于依赖类型的成员的模板时,您必须在其前面添加关键字template。这是getResult printStuffsize_t value = a.template getResult<B>(); 的调用

的方式
typename

这类似于在引用依赖类型中的嵌套类型名时使用关键字typename。出于某种原因,关于嵌套类型的template的比特是众所周知的,但是typename对嵌套模板的类似要求是相对未知的。

请注意,一般语法结构有点不同。 template始终放在类型的全名前面,而A插在中间。

同样,只有在访问依赖类型的模板成员时才需要这样做,在上面的示例中,printStuff位于foo.getResult<>。当您在main中致电footemplate的类型不依赖,因此无需包含{{1}}关键字。

答案 1 :(得分:9)

根据C ++标准14.2 / 4,您的代码格式不正确:

  

成员模板专精的名称出现在后缀表达式中的.->之后,或 nested-name-specifier 在 qualified-id 中,postfix-expression或qualified-id显式依赖于template-parameter(14.6.2),成员模板名称必须以关键字{{1}为前缀}。否则,假定该名称命名非模板。

所以,你应该写template