指定数据成员为引用类型时有关类成员访问的问题

2024-04-01

#include <iostream>
struct Test{
    Test(int& r):rf(r){

    }
    int& rf;
};
int main(){
   int a = 0;
   Test t(a);
   decltype(t.rf) b;  
}

考虑上面的代码,编译器抱怨这样的代码是不规范的 https://godbolt.org/z/EzEqEx, 因为b是引用类型并且没有被初始化。但是根据以下规则,我想知道为什么类型b是引用类型吗?
dcl.type.simple#4 https://timsong-cpp.github.io/cppwp/n4659/dcl.type.simple#4

对于表达式 e,decltype(e) 表示的类型定义如下:

  • 如果 e 是命名结构化绑定 ([dcl.struct.bind]) 的无括号 id 表达式,则 decltype(e) 是结构化绑定声明规范中给出的引用类型;
  • 否则,如果 e 是不带括号的 id 表达式或不带括号的类成员访问, decltype(e) 是e 命名的实体的类型。如果不存在这样的实体,或者如果 e 命名了一组重载函数,则该程序是格式错误的;

并根据段落内容表达式参考#4 https://timsong-cpp.github.io/cppwp/n4659/expr.ref#4 says:

如果 E2 声明为具有类型“引用 T”,则 E1.E2 是左值;E1.E2的类型为T。否则,适用以下规则之一。

这意味着类型t.rf is int。我不得不说 [expr.ref] 部分没有说,这是含糊的,E1.E2仍然是一个参考(表达式的确切实体是什么E1.E2表示?)。只是说这样的表达是lvalue它的类型就是引用所指的类型。

我只在[expr]中找到了一个特殊的规则,那就是:
expr#5 https://timsong-cpp.github.io/cppwp/n4659/expr#5

如果表达式最初具有“对 T 的引用”类型([dcl.ref]、[dcl.init.ref]),则类型将调整为 T在进行任何进一步分析之前. 表达式指定引用所表示的对象或函数,并且表达式是左值或x值,具体取决于表达式。 [ 注意:在引用的生命周期开始之前或结束之后,行为是未定义的(请参阅[basic.life])。 ——《尾注》

这是否意味着在分析表达式之前t.rf, since rf类型为“reference to T”,应调整为int以及这样的表达式,即rf指定a它所指的。

所以,根据上述规则,结果decltype(t.rf)应该int,为什么编译器认为它是int&?


如果 E2 被声明为“对 T 的引用”类型,则 E1.E2 是左值; E1.E2 的类型为 T。否则,适用以下规则之一。

这意味着t.rf的类型是int。

事实上,这意味着该类型表达 t.rf是 int (类别是左值)。但命名的类型entity- 这是类成员 - 仍然是对 int 的左值引用,因此这是由decltype(t.rf).

E2 在上下文中定义如下:

[expr.ref]

将 postfix-expression.id-expression 缩写为 E1.E2,...

实体定义为:

[基础.预]

实体是值、对象、引用、结构化绑定、函数、枚举器、类型、类成员、位字段、模板、模板专业化、命名空间或包。

实体列表不包括表达式。 E2不是一个实体。它是命名(表示)实体的表达式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

指定数据成员为引用类型时有关类成员访问的问题 的相关文章

  • 自动从 C# 代码进行调试过程并读取寄存器值

    我正在寻找一种方法来读取某个地址的 edx 注册表 就像这个问题中所问的那样 读取eax寄存器 https stackoverflow com questions 16490906 read eax register 虽然我的解决方案需要用
  • Func 方法参数的首选命名约定是什么?

    我承认这个问题是主观的 但我对社区的观点感兴趣 我有一个缓存类 它采用类型的缓存加载器函数Func
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • Cygwin 下使用 CMake 编译库

    我一直在尝试使用 CMake 来编译 TinyXML 作为一种迷你项目 尝试学习 CMake 作为补充 我试图将其编译成动态库并自行安装 以便它可以工作 到目前为止 我已经设法编译和安装它 但它编译成 dll 和 dll a 让它工作的唯一
  • 为什么 POSIX 允许在只读模式下超出现有文件结尾 (fseek) 进行搜索

    为什么寻找文件结尾很有用 为什么 POSIX 让我们像示例中那样在以只读方式打开的文件中进行查找 c http en cppreference com w c io fseek http en cppreference com w c io
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • 使用向量的 merge_sort 在少于 9 个输入的情况下效果很好

    不知何故 我使用向量实现了合并排序 问题是 它可以在少于 9 个输入的情况下正常工作 但在有 9 个或更多输入的情况下 它会执行一些我不明白的操作 如下所示 Input 5 4 3 2 1 6 5 4 3 2 1 9 8 7 6 5 4 3
  • 使用安全函数在 C 中将字符串添加到字符串

    我想将文件名复制到字符串并附加 cpt 但我无法使用安全函数 strcat s 来做到这一点 错误 字符串不是空终止的 我确实设置了 0 如何使用安全函数修复此问题 size strlen locatie size nieuw char m
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • 已过时 - OpenCV 的错误模式

    我正在使用 OpenCV 1 进行一些图像处理 并且对 cvSetErrMode 函数 它是 CxCore 的一部分 感到困惑 OpenCV 具有三种错误模式 叶 调用错误处理程序后 程序终止 Parent 程序没有终止 但错误处理程序被调
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • 方法参数内的变量赋值

    我刚刚发现 通过发现错误 你可以这样做 string s 3 int i int TryParse s hello out i returns false 使用赋值的返回值是否合法 Obviously i is but is this th
  • 在 ASP.NET 中将事件冒泡为父级

    我已经说过 ASP NET 中的层次结构 page user control 1 user control 2 control 3 我想要做的是 当控件 3 它可以是任何类型的控件 我一般都想这样做 让用户用它做一些触发回发的事情时 它会向
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反

随机推荐