C++ constexpr const vs constexpr变量?

C++ constexpr const vs constexpr变量?,c++,c++11,constants,constexpr,C++,C++11,Constants,Constexpr,很明显,constexpr意味着const,因此通常可以看到: constexpr int foo = 42; // no const here 然而,如果你写: constexpr char *const str = "foo"; 然后,如果传递了-Wwrite字符串标志,GCC将生成“警告:从字符串常量到'char*'的不推荐的转换” 写作: constexpr const char *const str = "foo"; 解决了这个问题 那么constexpr const和const

很明显,constexpr意味着const,因此通常可以看到:

constexpr int foo = 42; // no const here
然而,如果你写:

constexpr char *const str = "foo";
然后,如果传递了-Wwrite字符串标志,GCC将生成“警告:从字符串常量到'char*'的不推荐的转换”

写作:

constexpr const char *const str = "foo";
解决了这个问题


那么constexpr const和constexpr真的是一样的吗?

您看到的错误消息与
constexpr
关键字本身无关

类似“foo”的字符串文字,如:

此字符串文本的类型为
const char*
。声明如下:

char *const str = "foo";
这会尝试将
const char*
值分配给
char*
值。生成的
char*
值是不可变的常量,但此时已发生错误:试图将
const char*
转换为
char*

示例中的
constexpr
关键字只是一种干扰,与错误无关。

否。说它们是相同的,意味着如果不生成与const版本功能相同的代码,不使用const将是无效的。

我发现这对创建安全的单身汉很有用。我还没有完全探讨过这一点,并且希望非常量constexpr还有其他有效的用途

例如,下面是需要非常量constexpr的代码:

从变量的全局定义开始:

int global_int_;
现在我们可以创建一个constexpr函数,返回对它的引用:

constexpr int& get_global()
{
    return global_int_;
}
现在,我们可以在其他地方使用该引用:

int main()
{
    constexpr int& i{ get_global() };
    // do stuff with i
    return 0;
}
现在我们可以使用
i
作为非常量int。如果隐含了常量,这将是不可能的


由于非常量constexpr是有效的,如果您使用的constexpr需要是常量,则需要显式声明它。

问题是,在变量声明中,
constexpr
始终将
常量
-ness应用于声明的对象<另一方面,code>const可以应用于不同的类型,具体取决于位置

因此

是等价的

constexpr char* p = nullptr;
constexpr char* const p = nullptr;
是等价的;两者都使
p
a
const
指针指向
char

constexpr const char* p = nullptr;
constexpr const char* const p = nullptr;

它们是等价的
constexpr
生成
p
a
const
指针。
const char*
中的
const
使
p
指向
const char

虽然为真,但我认为OP是正确的,它应该与错误有关
constepr
constepr const
应该是一样的。问题是const char*到char*的转换。结果值是常量还是常量表达式不是一个因素。此时已发生错误。同样的错误也会发生在一个普通的char*foo=“bar”上。
“foo”
的类型是
const char[4]
。你似乎在心里将
constexpr
附加到指针上,但我认为它是附加到字符上的。我100%知道字符串文字不能转换为
char*
,但每个
char
本身应该是
constepr
,因此文字应该(逻辑上)可以分配给
constepr char*
。不。constexpr附加到正在声明的对象。被声明的对象不是指针指向的单个字符,而是指针本身。这完全是一个骗局。C++14 constexpr not implicit const用于成员函数。@T.C.我提供了一个没有成员函数的非const constexpr示例,因此我不确定您的意思。这与C++14的更改无关。就像指针一样,
constexpr
应用于引用本身(这是一个no-op,因为引用无论如何都不能更改),而不是引用的对象。@t.C.关于C++11/14的事情你是对的,所以我修正了它。我的观点是,将const添加到上述代码中会删除有效的功能,这就是为什么不能暗示const的原因。这里的问题是“constexpr const”和“constexpr”的组合用法,这与链接的问题完全不同。@Sumudu,我完全同意,并投票重新打开问题。
constexpr const char* p = nullptr;
constexpr const char* const p = nullptr;
constexpr const char* p = nullptr;
constexpr const char* const p = nullptr;