c++ - 静态元组类成员的 constexpr 有链接器错误

标签 c++ c++11 constexpr

我有以下代码:

#include <iostream>
#include <tuple>

class T
{
    public:
        using Names = std::tuple<char const*, char const*>;
        static constexpr Names names {"First", "Second"};
};

int main()
{
    std::cout << std::get<0>(T::names);
}

因为 names 是一个 constexpr 我希望它能工作。但是我收到链接器错误:

编译器:

> g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix

错误:

> g++ -std=c++1y pl.cpp
Undefined symbols for architecture x86_64:
  "T::names", referenced from:
      _main in pl-377031.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

[live demo]

最佳答案

static 的声明类中的数据成员永远不是定义1
每当变量被 odr-used2 时,定义是必要的。 std::get<> 每个引用 接受参数,并将变量绑定(bind)到引用 odr-立即使用它3

简单定义names外面:

constexpr T::Names T::names; // Edit: This goes *outside* the class "as is"!

Demo .


1) [basic.def]/2:

A declaration is a definition unless [..] it declares a static data member in a class definition (9.2, 9.4)

2) [basic.def.odr]/4:

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.

3) 根据 [basic.def.odr]/3:

A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.19) that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (4.1) is applied to e, or e is a discarded-value expression (Clause 5).

这里是 id-expression T::names指的是有问题的变量。唯一的超表达式 e包含 T::names 的所有潜在结果是T::names本身,因为函数调用的潜在结果集,即 std::get<0>(T::names) , 是空的。但是,显然没有应用左值到右值的转换,T::names 的值也显然没有被丢弃(因为它被传递给了一个函数)。
因此它是 odr-used 并且需要一个定义。

关于c++ - 静态元组类成员的 constexpr 有链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28134744/

相关文章:

c++ - 在没有线程支持的程序加载的共享库中使用 C++11 多线程

c++ - constexpr 上下文中的 std::optional 赋值运算符

c++ - 在引用定义中使用 constexpr 和 const

c++ - 不指定参数的调用方法

c++ - gcroot 的这种用法安全吗?

c++ - QTWebkit "headless"模式

c++ - cmake将中间文件放置到某个目录

c++ - static_assert 检查非模板类的模板构造函数中的值

c++ - 如何在可执行文件中存储 C++ 源代码?

c++ - 是否可以为 AVR 编写一个 constexpr 舍入函数?