C ++:constexpr对变量暗示隐式const不适用于引用[重复]

Posted

技术标签:

【中文标题】C ++:constexpr对变量暗示隐式const不适用于引用[重复]【英文标题】:C++: constexpr implying implicit const to variables does not apply to reference [duplicate] 【发布时间】:2021-05-25 22:16:46 【问题描述】:

关于 constexpr 表达式的问题有很多问题/答案,但我有一个问题与其他问题非常接近,但在另一种意义上略有不同。反正就是这样。

#include <iostream>
using namespace std;
                       
constexpr int x = 1; // TAG A

int main() 
   constexpr int &xf = x; // TAG B error out
   const int &xf1 = x; // TAG C works
   constexpr int const &xf2 = x; // TAG D works
   return 0;

错误:

Binding reference of type 'int' to value of type 'const int' drops 'const' qualifier [reference_bind_drops_quals]

评论:

    标签 A 清楚地表明 x 是 const int。根据 C++ Primer 第 5 版第 2.44 页“变量 声明为 constexpr 是隐式 const 并且必须由常量初始化 表达式:“。所以这很好。 TAG B --> 错误消息暗示 constexpr 没有隐含地“const”变量 xf。因此 xf 是 int &。这与 TAG A 相矛盾。为什么? TAG C --> 这是对 const 的常用引用 TAG D --> 由于它在 TAG B 中的行为方式,添加了额外的“const”以使其成为 const 引用。

“对 const 的引用”和“const 引用”这两个词有区别吗? 似乎对 const 的引用意味着引用是指一个 const 对象,但不允许进行修改,而“const 引用”是指引用是 const 但它可以指向 const 或非 const 对象。

这是一件令人困惑的大事。

【问题讨论】:

【参考方案1】:

"reference to a const"和"const reference"这两个词有区别吗

是的,从概念上讲,但是“const 引用”在逻辑上折叠为“引用”,因为从技术上讲,所有引用都是常量。这也是该语言不允许您将引用明确声明为const 的原因。 也就是说,在语言中仍然存在讨论“常量引用”的情况。考虑以下示例:

typedef int &intref;

int main() 
    int x = 0;
    const intref xf = x;
    return 0;

在这种情况下,xf 实际上是一个 const 引用(不是对 const 的引用),并且声明仍然有效。这会给你一个关于 const 限定符被忽略的警告,但它仍然会编译和运行。这说明了为什么严格遵守申报顺序规则仍然很重要。

要理解此声明的下一个非常重要的信息是constexpr 关键字的应用,以及当我们说它“暗示const”时的确切含义。 constexpr 关键字总是引用声明中的对象(而不是类型),所以当我们说 constexpr 暗示 const 时,这意味着在手摇的意义上,你可以省略 const 关键字constexpr 声明(本例中为xf)的最内层部分,因为它是多余的。在引用的特殊情况下,它不仅是多余的,而且是不允许的。您可能会争辩说编译器抛出错误有点不必要,因为您可以使用 typedef 绕过它,但原则仍然适用,就像应用缺少的 const 的规则一样。

将所有这些放在一起,在您的示例中,您可以大声朗读声明 B,如下所示:

"xf 是一个 constexpr,它是一个整数的引用(根据定义是 const,因此不需要暗示 const)。"

但是这里有一个问题,因为我们试图声明一个对非常量对象的引用并将它分配给一个常量对象。这正是编译器所抱怨的。

另见this。

【讨论】:

你提到的 const 的定义是引用不允许重新指向不同的对象。我明白了。我看到 constexpr int &xf = x;与 const int &x; 没有什么不同这里的常量是引用不允许修改指向的对象,因为后者是常量。我只是不明白为什么 constexpr int &xf = x;不等于 const int &xf=x,因为根据 C++ Primer constexpr 将隐含 const。 你提到“但是这里我们有一个问题,因为我们试图声明对非常量对象的引用......” - >这是混淆的部分。我将其视为声明对 const .. 的引用,因为 constexpr int &xf = x .. 我将其视为 const int &xf=x;我认为我困惑的根源是为什么 constexpr int &xf 不能转换为 const int &xf; 这是一个非常微妙的观点,我确实理解其中的困惑。让我花一些时间尝试重新制定答案,希望它会有所帮助。我不确定我是否可以在这些评论块中提供足够的信息。 我了解您使用的 typedef 示例。我也理解这部分..“”xf是一个constexpr,它是一个整数的引用(根据定义,它是const,因此不需要暗示const)。”所以使用等效阅读constexpr int x = 1;(TAG A ) .. 它将是“x 是一个 constexpr,它是一个 int,它隐含地暗示(添加)了 const。所以这里的区别是对于 xf 它不需要添加 const 因为它是多余的但对于 x 不是。你能确认我的评估是否正确吗?谢谢 没错@yapkm01。另一种思考方式可能是:编译器查看 xf,将 const 添加到其中,但 xf 作为引用已经是 const,所以没有什么特别的事情发生。另外我不确定为什么这个问题被标记为重复。实际上,IMO 似乎是一个稍微不同的问题。【参考方案2】:

B 中的constexpr 指的是变量xf,而不是类型(int &amp; constexpr xf;,虽然我不知道这是否会编译)。变量xfconstexpr,它的类型为int &amp;。这就是尝试将其绑定到 x 失败的原因。

【讨论】:

Thx 但我认为仅供参考,只有较低的 const 级别。指针可以有 top 和 lower const 但不能有引用。 @yapkm01 我觉得这有点令人困惑。我已经删除了 iit。 据我了解, constexpr 将隐式添加 const 限定符。因此它将是 const int &xf 而不是 int &xf 为什么是 constexpr int x=1;有类型.. const int 而不是 int? constexpr int x=1 明显改变了类型。这和上面的解释不矛盾吗?

以上是关于C ++:constexpr对变量暗示隐式const不适用于引用[重复]的主要内容,如果未能解决你的问题,请参考以下文章

解读C++ constexpr关键字的特性

C++14的这些新特性,你都知道吗?

C++14的这些新特性,你都知道吗?

未捕获 constexpr 变量

constexpr 是不是暗示 noexcept?

C++14的这些新特性,你都知道吗?