调用模板化成员的模板化方法

Calling templated method of templated member

本文关键字:方法 成员 调用      更新时间:2023-10-16

我有这个代码,它不编译(编辑:在VC中编译,但不在GCC中):

template<int N>
struct List
{
   template <class C>
   void clear() { }
};
template <int L>
class Test
{
public:
    List<L> list; // <--This line
    void method()
    {
       list.clear<int>(); // <-- Compile error here:  error: expected primary-expression before ‘int’
    }
};

我怎样才能使它工作?似乎编译器(gcc)不理解上下文,因为如果在标记行中我将L替换为一个数字,如list <1> list;

当您使用Test的模板参数实例化List时,它将成为一个依赖于的模板。编译器在解析Test时不能实例化它,因为它还不知道L的值,而且它知道List可能对L的不同值进行不同的专门化。所以编译器不能确定clear是一个模板,并得到混淆。您必须添加template关键字来消除歧义,如:

list.template clear<int>();
//   ^^^^^^^^ here just before the dependent template

当你用1代替L时,模板不再依赖于封闭模板的参数,所以编译器实例化并看到clear是一个模板,不需要消歧。

依赖模板的所有成员都需要消歧。编译器总是假定它们是值(函数或数据),因此必须用typename消除类型的歧义,用template消除模板的歧义。

template关键字的使用是规范的一部分。MSVC可以在没有它的情况下解析许多情况,包括这个情况,但它是MSVC 扩展。Gcc在这里要求template关键字是正确的。

您需要将template关键字放在clear之前以帮助编译器:

list.template clear<int>();
     ~~~~~~~~