警告:ISO C++禁止将字符串常量转换为'char*'以获取静态`constexpr char*`数据成员

tma*_*ric 31 c++ static constexpr c++11

为什么此代码会返回警告

警告:ISO C++禁止将字符串常量转换为'char*'[ - WRrite-strings]

如果

在对象声明或非静态成员函数中使用的constexpr说明符(直到C++ 14)暗示const.函数或静态成员变量(自C++ 17)声明中使用的constexpr说明符暗示内联.

(cppreference.com)

#include <cassert>    
#include <string>    
#include <iostream>    

struct A     
{    
    // warning: ISO C++ forbids converting a string constant to ‘char*’    
    static constexpr char* name_ = "A";                           
    static constexpr char* name() { return name_; };             
};                                             

int main()    
{};    
Run Code Online (Sandbox Code Playgroud)

如果我添加一个constconstexpr,警告消失了:

#include <cassert>    
#include <string>    
#include <iostream>   



struct A     
{    
    static constexpr const char* name_ = "A";    
    static constexpr const char* name() { return name_; };    
};                                             

int main()    
{};  
Run Code Online (Sandbox Code Playgroud)

随着g++ --version = g++ (GCC) 8.2.1 20181127,

汇编g++ -O3 -std=c++2a -Wall main.cpp -o main.

请问constexpr并不意味着conststatic数据成员?

Nat*_*ica 46

constexpr确实意味着const,但在这种情况下,它适用const于"错误的东西".

constexpr char*
Run Code Online (Sandbox Code Playgroud)

基本上是一样的

char * const
Run Code Online (Sandbox Code Playgroud)

这是一个指向非const的常量指针char.这不起作用,因为字符串文字具有类型,const char[N]因此它会抛弃数组元素的常量.

constexpr const char*
Run Code Online (Sandbox Code Playgroud)

另一方面,基本上是一样的

char const * const
Run Code Online (Sandbox Code Playgroud)

这是一个常量指针char,它是你想要的,因为它保留了元素的常量.


Ser*_*eyA 11

常量指针和指向常量的指针之间通常存在差异.通过让你constexpr char*自己成为一个指针constexpr(当然,const),但它仍然试图指向非常量字符 - 这是错误的,因为字符串文字是const.解:

constexpr const char* ch = "StackOverflow!";
Run Code Online (Sandbox Code Playgroud)

其中声明constexpr指针const.

  • 我记得规则 `const` 绑定到它紧靠左边的东西(除非它是第一个,在这种情况下它绑定到它紧靠右边的东西)。在我的代码中,我倾向于支持一般情况,而不是括号中的一般规则。`constexpr`,当我使用它时(不经常使用),我总是把它放在左边作为第一件事。我还没有被 OP 的情况所困扰。 (2认同)