为什么 C++ 中不存在成员引用?

2023-12-11

在 C++ 中,我可以在函数指针和函数引用之间进行选择(甚至为了完整性而选择函数值):

void call_function_pointer (void (*function)()) {
    (*function) ();
}
void call_function_reference (void (&function)()) {
    function ();
}
void call_function_value (void function()) {
    function ();
}

然而,当谈到方法时,我似乎在指针和引用之间没有这种选择。

template <class T> void call_method_pointer (T* object, void (T::*method)()) {
    (object->*method) ();
}
// the following code creates a compile error
template <class T> void call_method_reference (T& object, void (T::&method)()) {
    object.method ();
}

这让我假设 C++ 中不存在方法引用。真的吗?如果是,它们不存在的原因是什么?


在标准中(例如N3337- 不是最新的,但很好)第 8.3.3.3 节末尾有一条注释,内容如下:

[注:另见 5.3 和 5.5。 “指向成员的指针”类型是不同的 来自“指针”类型,即仅声明指向成员的指针 通过指向成员声明符语法的指针,而不是通过指针 声明符语法。 C++ 中没有“成员引用”类型。 — 尾注]

另外,当然,不存在“对成员的引用”类型运算符(假设,我能想到的最好的方法是->& and .&,尽管这些与数据和函数引用的取消引用不一致,这不需要特殊的运算符)。

Why?

至于为什么;经过一次有趣的小历史调查并未能找到任何现有的注释(我一路回到前端2.0其中首次支持成员指针罢工> --编辑:根据一份更可信的文件,该功能实际上是在 Cfront 1.2 中首次支持的),我问了这个人本人,他的答复如下:



Date: Sat, 22 Feb 2014 10:12:51 -0500
From: Bjarne Stroustrup <...>
Subject: Re: On lack of reference-to-member and CFront 2.0

On 2/22/2014 6:40 AM, Jason C wrote:
> My question is: C++ very clearly disallows the concept of 
> "reference-to-member". Why is this? I have been doing a lot of 
> research, and I traced the origin of "pointer-to-member" back (I 
> think) to 1989 CFront 2.0. I read through the product reference manual 
> and other documentation hoping to find an explanation of some sort but 
> could not.

I don't really remember. It was 25+ years ago and the ARM is silent on 
this. I added pointers to members to eliminate the need for a rare 
breakage of the type system. I suspect that I didn't add references to 
members because it did not seem worth the effort: there was no use case.
  

老实说,我期待的是更加神秘和复杂的事情。

所以你明白了:下次有人问为什么没有对成员的引用时,你可以自信地说,“因为没有!”(注:请参阅我在评论中的胡言乱语;仍需进行一些历史调查才能获得 100% 的置信度。)

就我个人而言,我从未在自己的代码中发现过成员指针的用途,但 Stroustrup 给出了它们存在的明显理由C++ 的演变:1985-1989,第 222-223 页。


顺便说一下,调用假设的成员函数引用的语法:

object.method();

...没有多大意义,因为没有办法在语法上区分它与对名为的实际成员的调​​用method().

hvd 在下面提出了一个很好的观点:正如您从上面看到的,从语法上讲,实际上并没有一种一致的方法来取消引用对成员的引用。您必须将其与普通成员访问区分开来,但同时您希望使其与对象和函数引用的取消引用(不需要特殊运算符)保持一致,而且我真的想不出有什么可以实现这两者。

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

为什么 C++ 中不存在成员引用? 的相关文章

  • 向 ExpandoObject 添加方法时,“关键字 'this' 在静态属性、静态方法或静态字段初始值设定项中无效”

    我尝试向 ExpandoObject 添加一个动态方法 该方法将返回属性 动态添加 给它 但它总是给我错误 我在这里做错了什么吗 using System using System Collections Generic using Sys
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • 如何使用recv()检测客户端是否仍然连接(并且没有挂起)?

    我写了一个多客户端服务器程序C on SuSE Linux 企业服务器 12 3 x86 64 我为每个客户端使用一个线程来接收数据 我的问题是 我使用一个终端来运行服务器 并使用其他几个终端来运行服务器telnet到我的服务器 作为客户端
  • C++ 异步线程同时运行

    我是 C 11 中线程的新手 我有两个线程 我想让它们同时启动 我可以想到两种方法 如下 然而 似乎它们都没有按照我的预期工作 他们在启动另一个线程之前启动一个线程 任何提示将不胜感激 另一个问题是我正在研究线程队列 所以我会有两个消费者和
  • 暂停下载线程

    我正在用 C 编写一个非常简单的批量下载程序 该程序读取要下载的 URL 的 txt 文件 我已经设置了一个全局线程和委托来更新 GUI 按下 开始 按钮即可创建并启动该线程 我想要做的是有一个 暂停 按钮 使我能够暂停下载 直到点击 恢复
  • IronPython:没有名为 json 的模块

    我安装了 IronPython 我的 python 文件如下所示 import sys print sys version import json 运行它的代码 var p Python CreateEngine var scope p C
  • Qt 创建布局并动态添加小部件到布局

    我正在尝试在 MainWindow 类中动态创建布局 我有四个框架 它们是用网格布局对象放置的 每个框架都包含一个自定义的 ClockWidget 我希望 ClockWidget 对象在调整主窗口大小时相应地调整大小 因此我需要将它们添加到
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 在 C 中使用 GNU automake 中的解析器

    我是 GNU autotools 的新手 在我的项目中使用了 lex 和 yacc 解析器 将它们作为 makefile am 中的源代码会产生以下错误 配置 in AC CHECK PROGS YACC bison yacc none i
  • 当模板类不包含可用的成员函数时,如何在编译时验证模板参数?

    我有以下模板struct template
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • System.Runtime.InteropServices.COMException(0x80040154):[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在 C 项目中遇到异常 System Runtime InteropServices COMException 0x80040154 检
  • 什么是 __declspec 以及何时需要使用它?

    我见过这样的例子 declspec在我正在阅读的代码中 它是什么 我什么时候需要使用这个构造 这是 Microsoft 对 C 语言的特定扩展 它允许您使用存储类信息来赋予类型或函数属性 文档 declspec C https learn
  • 转到定义:“无法导航到插入符号下的符号。”

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我今天突然开始在我的项目中遇到一个问题 单击 转到定义 会出现一个奇怪的错误 无法导航到
  • 运算符“==”不能应用于“int”和“string”类型的操作数

    我正在编写一个程序 我想到了一个数字 然后计算机猜测了它 我一边尝试一边测试它 但我不断收到不应该出现的错误 错误是主题标题 我使用 Int Parse 来转换我的字符串 但我不知道为什么会收到错误 我知道它说 不能与整数一起使用 但我在网
  • 使用 C# 从 DateTime 获取日期

    愚蠢的问题 给定日期时间中的日期 我知道它是星期二 例如我如何知道它的 tue 2 和 mon 1 等 Thanks 您正在寻找星期几 http msdn microsoft com en us library system datetim
  • WinRT 定时注销

    我正在开发一个 WinRT 应用程序 要求之一是应用程序应具有 定时注销 功能 这意味着在任何屏幕上 如果应用程序空闲了 10 分钟 应用程序应该注销并导航回主屏幕 显然 执行此操作的强力方法是在每个页面的每个网格上连接指针按下事件 并在触
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在
  • 匿名结构体作为返回类型

    下面的代码编译得很好VC 19 00 23506 http rextester com GMUP11493 标志 Wall WX Za 与VC 19 10 25109 0 标志 Wall WX Za permissive 这可以在以下位置检

随机推荐

  • 如何让所有浏览器都支持 ?还有其他选择吗?

    我正在使用 HTML5 元素输入属性 只有 Google Chrome 支持日期 时间属性 我试过现代化但我无法理解如何将其集成到我的网站上 如何编码 语法 包含是什么 有关如何在所有浏览器中使用日期 时间属性的任何代码片段 任何不支持输入
  • #define 内的 #ifdef

    我想写这样的东西 define COV ON x ifdef COVERAGE TOOL Pragma COVERAGE x endif 有什么方法可以定义COV ON像这样 我知道我上面所做的事情是错误的 因为我不能这样做 ifdef在
  • 如何为位掩码创建 48 位 uint

    我正在尝试创建一个 48 位整数值 我知道可以使用字符数组或结构 但我希望能够进行位掩码 操作 并且我不确定如何做到这一点 目前该程序使用16位uint 我需要将其更改为48 它是一个字节码解释器 我想将内存寻址扩展到4GB 我可以只使用
  • Highcharts和表格数据的导出

    我已经搜索了一下 但无法找到关于如何将数据表与高图一起导出的明确解决方案 一篇 stackoverflow 帖子指着这个资源 现在不可用 有人成功地做到了这一点吗 请参考这篇文章 高图表链接 另请参阅Fiddle for code
  • 在您的应用程序中显示 iPhone 应用程序设置

    iPhone 支持一种定义应用程序设置的方法 以便它会在 设置 应用程序中自动创建 UI 我还想允许用户在应用程序内编辑应用程序设置 但最好重用自动创建的相同 UI See 应用程序设置 有没有办法让您的应用程序使用与 设置 应用程序相同的
  • 使用 xslt 的 CSV 到 XML - 如何具有递增的列名称

    我有这个 xslt 将 csv 转换为 xml 工作正常 除了所有列的标签都相同 我需要它像这样增加
  • ListView 并从项目中的子视图传播单击事件

    我有一个带有自定义项目的 ListView 3 个 ImageView 和一个 TextView 我有电话要打给setItemsCanFocus true 这样我就可以使 ImageViews 可点击 我目前正在使用 SimpleAdapt
  • 使用 PHP 截断浮点数

    当一个浮点数需要截断为浮点后的某个数字时 事实证明这并不容易做到 例如 如果必须截断到点后的第二位数字 则数字应该是 45 8976 gt 45 89 0 0185 gt 0 01 点后第二位数字不按点后第三位数字四舍五入 功能类似于rou
  • 如何判断一种颜色是否接近另一种颜色

    我正在创建一种颜色工具 该工具应该告诉我颜色是否接近另一种颜色 例如 Color colors new colors Color FromArgb 0 0 255 Color FromArgb 0 109 251 colors 0 IS B
  • href 链接中的 laravel 方法?

    我想创建一个带有两个链接的下拉菜单 删除 和 编辑 链接 对于删除功能 我创建了一个表单 Former horizontal open gt method DELETE gt action action Test TestControlle
  • 转换unix时间戳php

    我有一个数据库来存储我的时间 我使用 PHP 插入它 date Y m d H i s 然后我使用这个函数将其转换为 PHP 中的 unix 时间戳 function convert datetime str list date time
  • 线程 - wait()

    The wait 对象上的方法只能在同步上下文中调用 即当前线程必须拥有对象上的锁才能调用wait 方法 现在如果线程 T1 拥有对象上的锁 obj 并调用其 wait 方法obj wait 其他线程如何获得该对象的锁定 obj 这样他们也
  • 为什么Eclipse将maven运行时依赖变成编译依赖?

    我有一个 Maven 项目导入到 Eclipse Oxygen 中 Eclipse 报告没有编译问题 Alt F5 当我从命令行运行 Maven 时 我得到 ERROR home dean src TAP3UIs TAP3Desktop s
  • 我尝试在不同线程上使用 OpenGL 和 Windows API

    所以基本上我正在使用窗口 API创建一个空窗口 然后我使用OpenGL从不同的线程绘制到该窗口 我设法做到了这一点仅用一根线程 但是获取和分派系统消息以使窗口可用会减慢我能够获得的帧速率 因此我试图在主线程中绘制时让另一个线程并行执行此操作
  • 加号解码为空格

    我从 ios 和 android 发送请求到一些 PHP 服务器 并且 GET 请求中的一些参数被错误解码 request http myserver com path email john doe GET email john doe i
  • --no-ff merge 如何打破平分和指责?

    了解 Git 工作流程文章说 因此 您添加了一条新规则 当您合并功能分支时 请使用 no ff 强制进行新的提交 这样就完成了工作 然后你就可以移动了 在 然后有一天 您在生产中发现了一个严重的错误 并且您需要 追踪它的推出时间 你跑平分但
  • PHP:无法从 DOMDocument 中删除节点

    我无法从 DOMDocument 中删除节点 获取异常 My Code
  • matplotlib/seaborn 中时间直方图中的轴刻度

    我有一个 df 其中包含来自 WhatsApp 聊天的消息 发件人以及日期时间格式的相应时间 Time Sender Message 2020 12 21 22 23 00 Sender 1 2020 12 21 22 26 00 Send
  • 使用 Discord.py 在一条消息中发送多个嵌入内容

    我一直在尝试使用discord py 在一条消息中发送嵌入列表 我在discord py的文档中看到这是可能的 https discordpy readthedocs io en latest api html 发送 内容 无 等待 假 用
  • 为什么 C++ 中不存在成员引用?

    在 C 中 我可以在函数指针和函数引用之间进行选择 甚至为了完整性而选择函数值 void call function pointer void function function void call function reference v