这个问题引用了我之前的问题:clang does not compile my code, but g++ does .根据我的研究,关键问题归结为链接,静态变量 data
在下面的示例中是否有链接(它使用 g++-4.8.1
编译)?它怎么会有链接(否则我无法使用非类型模板参数实例化)?
template <int const* ptr>
void foo()
{
}
typedef void (*func_type)();
template <int = 0>
void run_me()
{
static int data;
func_type const f1 = foo<&data>;
// auto f2 = foo<&data>; // doesn't work with gcc
// foo<&data>(); // doesn't work with gcc
}
int main(int, char*[])
{
run_me();
return 0;
}
标准的强制性引用:
非类型、非模板模板参数的模板参数应为以下之一: ...
——常量表达式(5.19),指定具有静态存储持续时间的对象的地址,并且 外部或内部链接或具有外部或内部链接的函数,包括函数模板 和函数模板 ID 但不包括非静态类成员,表示(忽略括号)为 & id-expression,除了如果名称引用函数或数组时 & 可以省略并且应 如果相应的模板参数是引用,则省略;或者 ...
最佳答案
在函数(无论是否为模板函数)中声明的静态变量肯定没有链接。
§3.5 段。 8:“除非特别注明,在 block 作用域 (3.3.3) 声明的名称没有链接”
据我所知,该条款中列出的唯一异常(exception)情况在第 1 段中提供。 6:“在 block 作用域中声明的函数名和在 block 作用域外部声明中声明的变量名具有链接。”
但是,14.3.2 可能会在某个时候放宽。
Daniel Krügler 提交了 DR 1451在 2012-02-01:
According to 14.3.2 [temp.arg.nontype] paragraph 1 bullet 3, only objects with linkage can be used to form non-type template arguments. Is this restriction still needed? It would be convenient to use block-scope objects as template arguments.
DR 已关闭,因为它是延期请求,应由演进工作组处理。它似乎已包含在n3413中, “允许非类型模板参数的任意文字类型”。
因此可以想象,一个或多个 C++ 编译器可能会选择对非类型模板参数实现更宽松的限制。
关于c++ - 模板函数中的静态对象是否有链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17348611/