为什么 constexpr 看起来并不意味着 char* 为 const?

问题描述 投票:0回答:3

很明显 constexpr 意味着 const,因此很常见:

constexpr int foo = 42; // no const here

但是如果你写:

constexpr char *const str = "foo";

如果传递了 -Wwrite-string 标志,GCC 将生成“警告:不推荐从字符串常量到‘char*’的转换”。

写作:

constexpr const char *const str = "foo";

解决问题。

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

c++ c++11 pointers constants constexpr
3个回答
109
投票

问题在于,在变量声明中,

constexpr
始终将
const
-ness应用于声明的对象;
const
另一方面可以适用于不同的类型,具体取决于位置。

因此

constexpr const int i = 3;
constexpr int i = 3;

是等价的;

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

是等价的;两者都使

p
成为指向
const
char
指针。

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

是等价的。

constexpr
使
p
成为
const
指针。
const
中的
const char *
使
p
指向
const char


7
投票

您看到的错误消息与

constexpr
关键字本身无关。

像“foo”这样的字符串文字,如:

somefunction("foo");

这个字符串文字的类型是

const char *
。以下声明:

char *const str = "foo";

这会尝试将

const char *
值分配给
char *
值。生成的
char *
值是不可变的、恒定的,但此时错误已经发生:尝试将
const char *
转换为
char *

示例中的

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


-2
投票

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

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

作为示例,以下代码需要非 const 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。如果 const 被隐含,这是不可能的。

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

© www.soinside.com 2019 - 2024. All rights reserved.