C++14静态constexpr成员数组在链接时失败

3
我在使用 static constexpr 属性时遇到了一些困难:它可以与整数类型和 enum class 成员一起使用,但当我尝试使用一个静态初始化的整数数组时,链接时会失败,并在 main 中显示 undefined reference to S::a

这是使用 clang 3.9 或 g++ 6.3 和 ld 2.27.90 时出现的情况;而且都是使用 -std=c++14
以下是最快的重现此问题的代码片段:
struct S
{
  static constexpr int a[5] = {0};
};


int main()
{
  S s{};
  [[gnu::unused]] int b = s.a[0]; // force S stuff to be emitted
  return 0;
}

感谢您对这种情况提出的任何建议。

你需要在命名空间作用域下定义你的对象:constexpr int S::a[5]; - ildjarn
@ildjarn 谢谢!但是你知道为什么我对数组要这样做,而对其他东西(如纯整数类型)不需要吗? - suut
1个回答

5

考虑以下代码:

enum class E { foo, bar };
struct S
{
  static constexpr int a[5] = {0};
  static constexpr int b = 42;
  static constexpr E e = foo;
};

以上所有内容都是声明,而不是定义。对于每一个声明,你必须提供一个定义:
int S::a[5];
int S::b;
E S::e;

它可以与整型和枚举类成员一起使用。

这在某种程度上更像是“偶然”发生的。具体地说,这是因为您从未在上下文中获取该变量的地址(从未使用该变量进行 ODR-use)。

我经常看到人们添加一个看似无害的 std::max 调用,并突然发现他们没有提供定义。也就是说:

int main()
{
   printf("%d\n", S::b);       // works fine
   int x = std::max(1, S::b);  // fails to link in non-optimized build.
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接