我使用的是c++ 14,我需要在我的类中使用静态的const字符串。但当我写
class myClass
{
static constexpr const std::string S="aa";
}
它不编译。编译器(g++)的结果是
type 'const string {aka const std::__cxx11::basic_string<char>}' of constexpr variable 'S::S' is not literal
如果我用char指针编写它,如下所示:
class myClass
{
static constexpr const *char S="aa";
}
这是汇编出来的。
我知道字符串可以在类之外初始化。我的问题是为什么第一种变体不被编译,第二种是。我想知道标准是什么。
发布于 2017-07-19 13:39:19
char
是一种基本类型(参考3.9.1基本类型basic.fundamental在草案n4296 for C++14中)。它既没有构造函数也没有析构函数,可以在constexpr
中使用。
另一方面,std::string
是一个类类型。更确切地说,它是basic_string
的一个专门化,即basic_string<char>
。basic_string
类有很多构造函数,包括在代码中使用的const char *
参数的构造函数,但是没有一个被声明为constexpr
,所以不能构建constexpr std::string
。这是有意义的,因为创建一个std::string
并不简单,它包含了一个char数组的动态分配:
basic_string(const图表* s,const分配器&a=分配器()); ..。第一个元素被s指向的数组的分配副本。
但是IMHO正确的方法是声明一个数组:
class myClass
{
static constexpr const char S[] ="aa";
}
const char A::S[]; // do not forget to define the static element if it is later odr-used...
顺便说一句,如果以后在程序中使用odr,静态数据成员将被定义在类定义之外。实现通常允许在类定义之外不定义积分常量或指针(无论如何,一个定义规则不需要诊断,未定义的行为允许预期的结果),但是严格的C++语义不需要。
参考n4296 C++14草案: 9.4.2静态数据成员class.static.data§3
如果非易失性const静态数据成员为整型或枚举类型,则类定义中的声明可以指定一个大括号或相等的初始化器,其中作为分配表达式的每个初始化器-子句都是一个常量表达式(5.20)。文本类型的静态数据成员可以在类定义中使用constexpr说明符声明;如果是,则其声明应指定一个大括号或相等的初始化器,其中作为赋值表达式的每个初始化器-子句都是一个常量表达式。注:在这两种情况下,成员可能以常量表达式出现。-end注意,如果在程序中使用odr (3.2),则成员仍应定义在名称空间范围内,并且命名空间范围定义不应包含初始化器。
https://stackoverflow.com/questions/45190999
复制相似问题