静态元组类成员的constexpr具有链接器错误 [英] constexpr of static tuple class member has linker error
问题描述
我有以下代码:
#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);
}
由于名称
为我希望 constexpr
可以工作。但是我得到一个链接器错误:
As names
is a constexpr
I expected this to work. But I get a linker error:
编译器:
> 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)
推荐答案
在类中声明 static
数据成员绝不是定义 1 。
每当变量被odr-used 2 使用时,都需要一个定义。
std :: get<>
接受每个引用的参数,并将变量绑定到引用odr-立即使用它 3 。
A declaration of a static
data member in class is never a definition1.
A definition is necessary whenever a variable is odr-used2.
std::get<>
takes arguments per reference, and binding a variable to a reference odr-uses it immediately3.
只需在外部定义名称
:
constexpr T::Names T::names; // Edit: This goes *outside* the class "as is"!
演示 。
1) [ basic.def] / 2:
1) [basic.def]/2:
声明是一个定义,除非[..]声明了
static
数据
类定义中的成员(9.2,9.4)
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:
2) [basic.def.odr]/4:
每个程序都应仅包含每个非内联$ b $的一个定义b在该程序中使用的函数或变量;不需要诊断
。
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:
3) According to [basic.def.odr]/3:
变量
x
的名称显示为可能值的表达式
ex
由ex
使用,除非应用左值到右值转换
( 4.1)到x
会产生一个常量表达式(5.19),该表达式不会调用
任何非平凡函数,如果x
是对象,ex
是
的元素,是表达式e $ c $的潜在结果集c>,其中将
左值到右值转换(4.1)应用于e
或e
是
的舍弃值表达式(第5条)。
A variable
x
whose name appears as a potentially-evaluated expressionex
is odr-used byex
unless applying the lvalue-to-rvalue conversion (4.1) tox
yields a constant expression (5.19) that does not invoke any non-trivial functions and, ifx
is an object,ex
is an element of the set of potential results of an expressione
, where either the lvalue-to-rvalue conversion (4.1) is applied toe
, ore
is a discarded-value expression (Clause 5).
此处的id表达式 T :: names
指的是有问题的变量。包含 T :: names
的所有可能结果的唯一超表达式 e
是 T: :names
本身,因为函数调用的可能结果集,即 std :: get< 0>(T :: names)
,是空的。但是,显然不应用从左值到右值的转换,并且显然也不会丢弃 T :: names
的值(因为将其传递给函数)。
因此它很常用,需要定义。
Here the id-expression T::names
refers to the variable in question. The only superexpression e
that contains all the potential results of T::names
is T::names
itself, because the set of potential results of a function call, i.e. std::get<0>(T::names)
, is empty. However, the lvalue-to-rvalue conversion is clearly not applied, and the value of T::names
is also clearly not discarded (as it is passed to a function).
Thus it is odr-used and requires a definition.
这篇关于静态元组类成员的constexpr具有链接器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!