我问自己为什么下面的代码工作,以及在实例化baz_instance时specifier extern所做的内容:
struct baz { int value; }; extern const baz baz_instance = {3}; template<baz const& b> int foo(){ return b.value; } int main(){ foo<baz_instance>(); return 1; }
为什么上面的代码首先编译,为什么不编译extern说明符呢?这个例子中extern说明符是做什么的?
解决方法
这是标准的一部分,从C 03改为C 11.
在C 03中,[temp.arg.nontype]读取:
A template-argument for a non-type,non-template template-parameter shall be one of:
- […]
- […]
- the address of an object or function with external linkage,including function templates and function template-ids but excluding non-static class members,expressed as & id-expression where the & is optional if the name refers to a function or array,or if the corresponding template-parameter is a reference; or
- […]
在C11中,由于issue 1155,GCC仍然有a bug的这种行为:
- a constant expression (5.19) that designates the address of a complete object with static storage duration
and external or internal linkage or a function with external or internal linkage,including function
templates and function template-ids but excluding non-static class members,expressed (ignoring parentheses)
as & id-expression,where the id-expression is the name of an object or function,except that the
& may be omitted if the name refers to a function or array and shall be omitted if the corresponding
template-parameter is a reference; or
在C 14中,这进一步简化,甚至没有提及联动.
对于您的具体问题,外部说明符将添加外部链接到baz_instance.没有它,baz_instance有内部联系.在C 03中,您需要外部链接才能使用引用类型的非类型模板参数.在C 11中,你不再需要 – 所以extern不再需要了,没有它就可以编译好.