3

我尝试使用可变参数创建一个外部模板,例如:

extern template<typename... XS> void log( XS... xs );

但是 gcc 7.2 没有编译它,并显示错误:

error: expected unqualified-id before ‘&lt;’ token

我检查了 c++11 中的 gcc 状态,extern 模板应该可以工作,不是吗?

4

1 回答 1

7

extern关键字的作用与您的预期不同 - 当然,如果我正确理解您的预期。

extern关键字应用于模板的显式实例化,它可以防止编译器在处理某个翻译单元时为该模板隐式生成代码。根据 C++11 标准的第 14.7.2/2 段:

显式实例化有两种形式:显式实例化定义和显式实例化声明。显式实例化声明以extern关键字开头。

如果没有关键字,编译器将在每个包含对 的调用的翻译单元中extern为(比如说)生成代码,并且该代码(对于所有翻译单元应该并且应该是相同的)最终将由链接器合并(链接器基本上会丢弃所有重复并只保留一个)。log(double, int)log(double, int)

extern关键字通过告诉编译器:“相信我,其他人会在其他地方实例化这个模板——你现在不需要这样做”,从而避免了编译时间的浪费。但这个承诺必须兑现

例如,如果您有这个主模板:

template<typename... Xs> void log(Xs... xs);

然后你声明这个显式实例化:

extern template void log(int, double);

比您必须在某些翻译单元中具有相应的显式实例化:

template void log(int, double)

否则,编译器将永远不会为 生成代码log<int, double>(int, double),并且链接器将抱怨未定义的引用。

于 2013-04-18T08:08:21.387 回答