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

时间:2014-05-12 05:15:41

标签: c++ templates

我有这个代码,它不能编译(编辑:在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&lt; 1&gt;列表; 然后编译好了。

2 个答案:

答案 0 :(得分:2)

当您使用List的模板参数实例化Test时,它将成为依赖模板。编译器在解析Test时无法对其进行实例化,因为它还不知道L的值,并且知道List可能对L的不同值有所区别。 }。因此,编译器无法确定clear是否为模板而感到困惑。您必须添加template关键字才能消除歧义:

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

L替换为1时,模板不再依赖于封闭模板的参数,因此编译器实例化并看到clear是模板,不需要消除歧义

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

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

有关详尽的讨论,请参阅this answer

答案 1 :(得分:0)

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

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