constexpr const 与 constexpr 变量?

constexpr const vs constexpr variables?

constexpr 隐含 const 似乎很明显,因此很常见:

constexpr int foo = 42; // no const here

但是如果你写:

constexpr char *const str = "foo";

如果传递了 -Wwrite-string 标志,那么 GCC 将生成 "warning: deprecated conversion from string constant to ‘char*’"。

写作:

constexpr const char *const str = "foo";

问题已解决。

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

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

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

somefunction("foo");

这个字符串文字的类型是const char *。以下语句:

char *const str = "foo";

这会尝试将 const char * 值分配给 char * 值。结果 char * 值是不可变的,常量,但到那时错误已经发生:尝试将 const char * 转换为 char *.

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

没有。说它们相同意味着没有时间不使用 const 是有效的,而不产生与 const 版本功能相同的代码。

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

例如,这里是需要非常量constexpr的代码:

从变量的全局定义开始:

int global_int_;

现在我们可以创建一个 constexpr 函数,returns 引用它:

constexpr int& get_global()
{
    return global_int_;
}

现在我们可以在其他地方使用该引用:

int main()
{
    constexpr int& i{ get_global() };
    // do stuff with i
    return 0;
}

我们现在可以将 i 用作非常量整数。如果隐含了 const,这是不可能的。

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

问题是在变量声明中,constexpr 总是将 const-ness 应用于声明的对象;另一方面,const 可以应用于不同的类型,具体取决于展示位置。

因此

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

等价;

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

是等价的;两者都使 p 成为指向 char.

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

是等价的。 constexpr 使 p 成为 const 指针。 const char *中的const使得p指向const char