在类模板参数上调用模板方法

时间:2018-07-27 07:58:22

标签: c++ templates

.cpp文件中的以下最小示例在VisualStudio 2017中导致编译器错误(15.7.4,启用了/ std:c ++ 17):

template <typename T>
class A
{
    void f(T& t)
    {
        t.g<2>();
    }
};

// B is a candidate for the template parameter T in A
struct B {
    template <int a>
    void g() {
        // nothing here
    }
};

编译器错误引用了A :: f()的主体并显示为:

error C2760: syntax error: unexpected token ')', expected 'expression' .

请注意,A和B都没有实际实例化。没有声明B也会发生相同的错误。

但是,如果我切换声明A和B的顺序,则示例将编译(并且A可以实例化)。这令人惊讶,因为我没有在代码中表达A和B之间的任何关系。另一个令人惊讶的事实是,在B :: g()的签名中添加参数(例如int)和g()的调用似乎也可以解决错误(无需更改声明的顺序)。

我的问题是: (1)上面的代码为什么会产生编译器错误? (2)如何以一种干净的方式解决它?

1 个答案:

答案 0 :(得分:2)

如果在模板类中使用模板,则必须告诉编译器这是模板。

template <typename T>
class A
{
    void f(T& t)
    {
        t.template g<2>();
    }
 };

有关.template::template用法的很好解释可以在这里找到:Where and why do I have to put the "template" and "typename" keywords?