0

这个问题是指我之前的问题:clang 不编译我的代码,但是 g++ 可以。根据我的研究,问题归结为链接,静态变量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 表达式,但如果名称引用函数或数组,则 & 可以省略,如果相应的模板参数是引用,则应省略;或者 ...

4

1 回答 1

3

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

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

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

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

Daniel Krügler于 2012-02-01提交了DR 1451 :

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

DR 被关闭是因为它是一个延期请求,应该由演进工作组处理。它似乎已包含在n3413中,“允许非类型模板参数的任意文字类型”。

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

于 2013-06-27T18:06:15.720 回答