【问题标题】:constexpr const vs constexpr variables?constexpr const 与 constexpr 变量?
【发布时间】:2015-05-04 21:16:44
【问题描述】:

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 真的一样吗?

【问题讨论】:

  • 这不是 Difference between constexpr and const 的副本。这里的问题是“constexpr const”与“constexpr”的组合用法,这与链接问题完全不同。
  • @Sumudu,我完全同意,我投票决定重新提出问题。

标签: c++ c++11 constants constexpr


【解决方案1】:

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

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

somefunction("foo");

这个字符串字面量的类型是const char *。以下声明:

char *const str = "foo";

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

您示例中的 constexpr 关键字只是分散注意力,与错误无关。

【讨论】:

  • 虽然是真的,但我认为 OP 是正确的,但它应该与错误有关。 constexprconstexpr const 应该是同一个东西。
  • 问题是 const char * 到 char * 的转换。结果值是 const 还是 constexpr 不是一个因素。到那时,错误已经发生了。仅使用普通 char *foo="bar" 也会发生相同的错误。
  • "foo" 的类型是const char [4]
  • 您似乎在精神上将constexpr 附加到指针上,但我认为它附加到了字符上。我 100% 知道字符串文字不能转换为 char*,但每个 char 本身应该是 constexpr,因此文字应该(逻辑上)是可分配给constexpr 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,这是不可能的。

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

【讨论】:

  • 这是一个完整的红鲱鱼。 C++14 constexpr-not-implicitly-const 用于成员函数。
  • @T.C.我提供了一个没有成员函数的非常量 constexpr 的示例,所以我不确定你的意思。
  • 这与 C++14 的变化无关。就像指针一样,constexpr 应用于引用本身(这是一个无操作,因为无论如何都不能更改引用)而不是引用的对象。
  • @T.C.你对 C++11/14 的事情是对的,所以我解决了这个问题。我的观点是,在上面的代码中添加 const 会删除有效的功能,这就是为什么不能隐含 const 的原因。
【解决方案3】:

问题在于,在变量声明中,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 char * 中的 const 使 p 指向 const char

【讨论】:

  • constexpr const char* p = nullptr;constexpr char* p = nullptr; 是否等效?
猜你喜欢
  • 2012-11-01
  • 2023-03-15
  • 2016-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 1970-01-01
  • 2020-10-08
相关资源
最近更新 更多