成员函数的 const 修饰符如何影响重载解析?

2023-11-23

我有以下测试代码:

#include <string>
#include <iostream>

class CString
{
public:
    CString(char const*) {}
};

class TestBed
{
public:
    void Comparison(CString const&) { std::cout << "CString Overload" << std::endl; }
    void Comparison(std::string const&) { std::cout << "std::string overload" << std::endl; }
};

int main()
{
    TestBed tb;
    tb.Comparison("Hello World");
}

此代码无法编译,因为调用Comparison()是模棱两可的。我期待这种行为。

然而,当我做任何一个Comparison()超载const,如:void Comparison(std::string const&) const or void Comparison(CString const&) const(但不是两者),代码编译并选择非常量重载。

重载解析规则非常复杂,我还没有看到任何描述如何进行的内容const影响这种情况。我的理解是:

  1. 首先选择具有精确匹配参数的函数
  2. 接下来尝试1级隐式转换

在这两种情况下,1 和 2 都是不明确的。有人可以解释一下吗?谢谢。


对于类方法,this部分被视为好像它是一个额外的参数。所以如果你做了CString一个常量,使重载集:

Comparison(const TestBed&, CString const&) // (1)
Comparison(TestBed&, std::string const&)   // (2)

For (1),我们需要进行两次转换:const转换,以及转换为CString。但对于(2),我们只需要进行一次转换:std::string. Thus, (2)是优选的。

我们可以通过添加第三个函数来验证这一点,该函数执行一次转换this:

Comparison(const TestBed&, const char*)  // (3)

在这里,我们再次只有一个转换(在“第一个”参数中),因此重载集是不明确的。


在[over.match.funcs]中:

成员函数被认为有一个额外的参数,称为隐式对象参数,它 表示已调用其成员函数的对象。出于重载决策的目的,静态和非静态成员函数都具有隐式对象参数,但构造函数没有。

对于非静态成员函数,隐式对象参数的类型为

— “对 cv X 的左值引用”对于没有引用限定符或使用 & 引用限定符声明的函数

— 对于使用 && 引用限定符声明的函数,“对 cv X 的右值引用”

其中 X 是该函数所属的类,cv 是该成员的 cv 限定 函数声明。 [ 示例:对于 X 类的 const 成员函数,假定额外参数为 具有类型“对 const X 的引用”。 —结束示例]

在重载解析期间,隐含的对象参数与​​其他参数无法区分。

这确立了我们考虑的原因const TestBed& vs TestBed&。然后只需比较重载之间的转换序列即可(1) and (2)。对于第二个参数,两个转换序列是相等的,但对于第一个参数,(2)具有更好的转换序列(即精确) - 这就是它毫无歧义地获胜的原因。

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

成员函数的 const 修饰符如何影响重载解析? 的相关文章

  • 进程何时获得 SIGABRT(信号 6)?

    C 中进程获得 SIGABRT 的场景有哪些 该信号是否始终来自进程内部 或者该信号可以从一个进程发送到另一个进程吗 有没有办法识别哪个进程正在发送该信号 abort 向调用进程发送SIGABRT信号 就是这样abort 基本上有效 abo
  • ASP.NET MVC 中的经典 ASP (C#)

    我有一个应用程序想要 最终 转换为 ASP NET MVC 我想要进行全面的服务升级 到 ASP NET 但想要使用当前的 ASP 内容来运行当前的功能 这样我就可以在对新框架进行增量升级的同时升级小部分 该站点严重依赖于不太成熟的 VB6
  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 为什么大多数 C 开发人员使用 Define 而不是 const? [复制]

    这个问题在这里已经有答案了 在许多程序中 define与常量具有相同的用途 例如 define FIELD WIDTH 10 const int fieldWidth 10 我通常认为第一种形式优于另一种形式 它依赖于预处理器来处理基本上是
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 32 位应用程序的特征最大矩阵大小

    所以 我正在寻找Eigen http eigen tuxfamily org index php title Main Page当我尝试声明大于 10000x10000 的矩阵时 包崩溃 我需要声明一个像这样的矩阵 可靠地大约有 13000
  • 暂停下载线程

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

    我安装了 IronPython 我的 python 文件如下所示 import sys print sys version import json 运行它的代码 var p Python CreateEngine var scope p C
  • 当前的 c++ 工作草案与当前标准有何不同

    通过搜索该标准的 PDF 版本 我最终找到了这个链接C 标准措辞草案 http www open std org jtc1 sc22 wg21 docs papers 2012 n3376 pdf从 2011 年开始 我意识到我可以购买最终
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • C 语言中 =+(等于加)是什么意思?

    我碰到 与标准相反 今天在一些 C 代码中 我不太确定这里发生了什么 我在文档中也找不到它 In ancientC 版本 相当于 它的残余物与最早的恐龙骨头一起被发现 例如 B 引入了广义赋值运算符 使用x y to add y to x
  • 将数据打印到文件

    我已经超载了 lt lt 运算符 使其写入文件并写入控制台 我已经为同一个函数创建了 8 个线程 并且我想输出 hello hi 如果我在无限循环中运行这个线程例程 文件中的o p是 hello hi hello hi hello hi e
  • 基于xsd模式生成xml(使用.NET)

    我想根据我的 xsd 架构 cap xsd 生成 xml 文件 我找到了这篇文章并按照说明进行操作 使用 XSD 文件生成 XML 文件 https stackoverflow com questions 6530424 generatin
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • 通过 NHibernate 进行查询,无需 N+1 - 包含示例

    我有一个 N 1 问题 我不知道如何解决它 可以在这个问题的底部找到完全可重复的样本 因此 如果您愿意 请创建数据库 设置 NUnit 测试和所有附带的类 并尝试在本地消除 N 1 这是我遇到的真实问题的匿名版本 众所周知 这段代码对于帮助
  • 如何一步步遍历目录树?

    我发现了很多关于遍历目录树的示例 但我需要一些不同的东西 我需要一个带有某种方法的类 每次调用都会从目录返回一个文件 并逐渐遍历目录树 请问我该怎么做 我正在使用函数 FindFirstFile FindNextFile 和 FindClo
  • g++ 对于看似不相关的变量“警告:迭代...调用未定义的行为”

    考虑以下代码strange cpp include
  • 耐用功能是否适合大量活动?

    我有一个场景 需要计算 500k 活动 都是小算盘 由于限制 我只能同时计算 30 个 想象一下下面的简单示例 FunctionName Crawl public static async Task
  • 是否可以在 C# 中强制接口实现为虚拟?

    我今天遇到了一个问题 试图重写尚未声明为虚拟的接口方法的实现 在这种情况下 我无法更改接口或基本实现 而必须尝试其他方法 但我想知道是否有一种方法可以强制类使用虚拟方法实现接口 Example interface IBuilder
  • 错误:无效使用不完整类型“类 Move”/未定义对 Move::NONE 的引用

    拜托 我不知道为什么这个简单的代码被拒绝 它给了我 2 个编译错误 请帮帮我 I use 代码 块 20 03 我的编译器是GNU GCC 移动 hpp class Move public Move Move int int public

随机推荐