模板函数中的静态对象是否具有链接?

时间:2013-06-27 16:36:38

标签: c++ templates c++11 g++

这个问题提到了我之前的问题: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),用于指定具有静态存储持续时间和的对象的地址 外部或内部链接或具有外部或内部链接的功能,包括功能模板 和函数template-ids但不包括非静态类成员,表示(忽略括号)为 &安培; id-expression,除了&amp;如果名称引用函数或数组,则可以省略 如果相应的模板参数是引用,则省略;要么 ...

1 个答案:

答案 0 :(得分:3)

当然,在函数中声明的静态变量(无论它是否是模板函数)都没有链接。

§3.5段。 8:“除非另有说明,否则在块范围内声明的名称(3.3.3)没有链接”

据我所知,该条款中列出的唯一例外情况见第7段。 6:“在块作用域中声明的函数的名称和由块作用域extern声明声明的变量的名称具有链接。”

但是,14.3.2可能会在某个时候放松。

DanielKrügler于2012-02-01提交了DR 1451

  

根据14.3.2 [temp.arg.nontype]第1段子弹3,只有具有连接的对象才能用于形成非类型模板参数。这个限制仍然需要吗?使用块范围对象作为模板参数会很方便。

DR是因为它是扩展请求而关闭的,应由Evolution工作组处理。它似乎已包含在n3413,“允许非类型模板参数的任意文字类型”中。

因此,当然可以想象一个或多个C ++编译器可能会选择对非类型模板参数实施更宽松的限制。