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成员)详细解读