首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么无法在类主体中初始化静态const字符串成员

为什么无法在类主体中初始化静态const字符串成员
EN

Stack Overflow用户
提问于 2017-07-19 12:43:33
回答 1查看 4.6K关注 0票数 4

我使用的是c++ 14,我需要在我的类中使用静态的const字符串。但当我写

代码语言:javascript
复制
class myClass
{
     static constexpr const std::string S="aa";
}

它不编译。编译器(g++)的结果是

代码语言:javascript
复制
type 'const string {aka const std::__cxx11::basic_string<char>}' of constexpr variable 'S::S' is not literal

如果我用char指针编写它,如下所示:

代码语言:javascript
复制
class myClass
{
     static constexpr const *char S="aa";
}

这是汇编出来的。

我知道字符串可以在类之外初始化。我的问题是为什么第一种变体不被编译,第二种是。我想知道标准是什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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正确的方法是声明一个数组:

代码语言:javascript
复制
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),则成员仍应定义在名称空间范围内,并且命名空间范围定义不应包含初始化器。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45190999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档