我有这个代码,它不能编译(编辑:在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;列表; 然后编译好了。
答案 0 :(得分:2)
当您使用List
的模板参数实例化Test
时,它将成为依赖模板。编译器在解析Test
时无法对其进行实例化,因为它还不知道L
的值,并且知道List
可能对L
的不同值有所区别。 }。因此,编译器无法确定clear
是否为模板而感到困惑。您必须添加template
关键字才能消除歧义:
list.template clear<int>();
// ^^^^^^^^ here just before the dependent template
将L
替换为1
时,模板不再依赖于封闭模板的参数,因此编译器实例化并看到clear
是模板,不需要消除歧义
需要消除依赖模板的所有成员的歧义。编译器始终假定它们是值(函数或数据),因此必须使用typename
和template
模板消除类型。
template
关键字的使用是规范的一部分。 MSVC可以解析许多情况,包括这个情况,没有它,但它是MSVC 扩展。 Gcc在此处要求template
关键字是正确的。
有关详尽的讨论,请参阅this answer。
答案 1 :(得分:0)
您需要在template
之前放置clear
关键字来帮助编译器:
list.template clear<int>();
~~~~~~~~