const 成员函数的重载解析 C++

Posted

技术标签:

【中文标题】const 成员函数的重载解析 C++【英文标题】:Overload resolution C++ for const member functions 【发布时间】:2014-02-23 12:03:16 【问题描述】:

假设你有一个有两个成员函数的类 T

    char foo() const ... char foo() ....

我的理解是,当需要一个常数 T 时,我们会解析为 (1);对于非常量 T,我们解决 (2)。

    对吗? 在此解析中调用了哪个规则? (参考标准很棒,但感谢提供有用的简短摘要)

注意事项:

    我试图用谷歌搜索它,但我在 SO 上获得的旧命中是其他涉及 const 的重载解决方案的案例。但是,链接到一个旧的 SO 实际上解释了上述内容显然很棒。

    在重新阅读 Stroustrup 的“C++ 编程语言”,第 2 版(“特别版”),第 11.12 节中的字符串/Cref 示例时出现了这个问题,p。 296. 由于 Stroustrup 如此精确,答案可能在前面的部分中,但我看不出在哪里。也非常欢迎参考 Stroustrup 中的部分(第二版最好,因为这是我拥有的)。第 10.2.6 节将 const 成员介绍为那些“不改变对象的值”的成员,这暗示了答案,但并没有让我觉得它是一个明确的解决指令。

【问题讨论】:

在高级视图中,您可以考虑编译器将执行的转换。成员函数将被转换为:char foo(T const *this)char foo(T *this)(详情暂且不谈)。 @David Rodriguez - dribeas:我明白了;而对于指针类型参数, const p 和 p 在重载决议中是有区别的,对吗?这确实给出了一些直觉。 我已经正确地重新格式化了您的问题。请花点时间阅读Markdown formatting help。 @Konrad Rudolph:感谢。问题是当我在远离计算机时使用 iPhone 时:我熟悉正确的格式,但已知手机会添加/删除不可打印的内容。它在我的手机上看起来正确,但不是。我通常在家编辑一次,但不想等到半夜才提问。 附加的T* / T const* 参数称为隐式对象参数(虽然它实际上是一个引用);我不明白为什么这应该是一个高级视图。隐式对象参数和实际函数参数之间存在一些细节差异,但 AFAIK 重载决议的大部分都平等地对待它们。见[over.match.funcs] 【参考方案1】:

在 N3242(我手头的标准草案)中,13.3.1 第 4 段说

隐式对象参数的类型是“对 cv X 的左值引用”,对于没有 ref-qualifier 或 & ref-qualifier

这意味着首先出现的隐式对象参数的类型是“对cv X的左值引用”,其中X是类,cv是成员变量的cv限定(即常量或非常量)。然后,重载决议继续正常进行。

要查看重载解决过程,首先,它们都被列为“候选”函数,因为它们在正确的范围内并且具有正确的名称。

const 的情况下,只有const 成员函数才能进入下一步(称为“生存能力”),因此它自动成为最佳选择。非常量成员函数不可行,因为您无法将 const 引用转换为非常量引用。

在非常量情况下,常量和非常量版本都是可行的,但非常量版本“更好”,因为下面引用了 13.3.3.2 第 3 段的第五条规则。

标准转换序列 S1 是比标准转换序列更好的转换序列 标准转换序列 S2 if ...

S1 和 S2 是引用绑定,而 除了*** cv 限定符之外,引用引用是相同的类型, 并且 S2 初始化的引用所指的类型更多 cv-qualified 比由 S1 初始化的引用的类型 参考。

【讨论】:

您的解释是有道理的,但是 (a) 引用不应该继续吗?它似乎是“if type is (...)”,但似乎错过了“then (...)”; (b) 引用适用于 tmember 函数,对吗? (引用仅表示功能。 抱歉,上面的句子中提到了它丢失了。现在有意义吗? 我看到你已经解决了(b)(谢谢); (一)呢? (或告诉我是否/为什么(a)无关紧要) 对不起,我不明白。我最近添加了更多上下文。基本上它是说,对于没有引用限定符(你的情况)声明的非静态成员函数,隐式对象参数是对 X 的引用,无论函数声明的 cv 状态是什么。我没有看到任何未满足的条件。 在那之后,重载决议将隐式对象参数视为与任何其他参数完全相同,只是它首先出现。

以上是关于const 成员函数的重载解析 C++的主要内容,如果未能解决你的问题,请参考以下文章

C++类和对象(构造函数析构函数拷贝构造函数赋值运算符重载Const成员)详细解读

C++类和对象(构造函数析构函数拷贝构造函数赋值运算符重载Const成员)详细解读

C++类和对象(构造函数析构函数拷贝构造函数赋值运算符重载Const成员)详细解读

C++类和对象

C++类和对象—— 类的6个默认成员函数及日期类的实现

C++点滴----关于类常成员函数