当前位置: 首页 > 知识库问答 >
问题:

C:constexpr暗示变量的隐式常量不适用于引用[重复]

暴博远
2023-03-14

有很多问题/答案有关的问题,但我有一个问题,非常接近其他问题,但在另一种意义上略有不同。不管怎样,它来了。

#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]

评论:

  1. 根据 C Primer 第 5 版第 2.44 页“声明为 constexpr 的变量是隐式的 const,必须通过常量表达式初始化:”。所以这很好。
  2. 标签 B --


似乎对const的引用意味着引用是指一个const对象,而不允许进行修改,而"const引用"是指引用是const,但它可以指向const或非const对象。

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

共有2个答案

谭梓
2023-03-14

B 中的 constexpr 是指变量 xf,而不是类型 (int

孙宏扬
2023-03-14

“对const的引用”和“const引用”这个词有区别吗?

是的,从概念上讲,但“常量引用”在逻辑上会变成“引用”,因为从技术上讲,所有引用都是常量。这也是为什么该语言不允许将引用显式声明为const。尽管如此,在语言中仍有一些情况下,谈论“常量引用”是有意义的。考虑以下示例:

typedef int &intref;

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

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

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

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

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

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

另见本。

 类似资料:
  • 考虑以下几点: 为什么第一个版本是编译错误,当我已经声明lambda是可变的,并通过值捕获(我认为是它的副本)? 使用clang(x86_64-apple-darwin14.3.0)和Visual C(vc120)进行测试,这是错误消息的来源。

  • 问题内容: from celery import Celery 这是我用来测试芹菜的代码。我希望每次使用addone()时,返回值都应该增加。但是为什么总是1? 结果 问题答案: 默认情况下,启动工作程序时,Celery以并发4启动它,这意味着它已启动4个进程来处理任务请求。(加上一个控制其他进程的进程。)我不知道该使用哪种算法将任务请求分配给为工作人员启动的进程,但是最终,如果执行足够,您将看到

  • 行为可以在这个小片段中看到(作为全局脚本执行): 该警报在Chrome中产生

  • 问题内容: 可以在以下小片段中看到该行为(将其作为全局脚本执行): 该警报在Chrome中产生,但在IE和Firefox中有效。当我这样做时,我也会得到一个怪异的价值 问题答案: window.name具有特殊用途,应该是字符串。Chrome似乎已将其显式转换为字符串,因此实际上最终为全局变量(即)提供了值。由于它是原始元素,因此属性()不会“粘滞”。 要解决此问题,请不要将其用作全局变量。

  • 我使用的OptaPlanner有两个规划变量,其中一个定义为nullable=true。遵循会议示例(为简单起见),假设Room可以为空,但Time不能为空。 我在非空的变量上定义了一个约束,但似乎只有当可空的变量不为空时,惩罚才起作用,否则会失败。 下面是我的代码片段: 在我的约束提供者类中,我定义了以下约束来确保一个人不能参加两个单独的会议: 当创建两个具有非空值的对象时,如果假设同一个人同时

  • Jekyll 会遍历你的网站搜寻要处理的文件。任何有 YAML 头信息的文件都是要处理的对象。对于每一个这样的文件,Jekyll 都会通过 Liquid 模板工具来生成一系列的数据。下面就是这些可用数据变量的参考和文档。 全局(Global)变量 变量 说明 site 来自_config.yml文件,全站范围的信息+配置。详细的信息请参考下文 page 页面专属的信息 + YAML 头文件信息。通