在C++中进行常量成员函数的重载决议

8
假设您有一个类T,其中包含两个成员函数:
  1. char foo() const {...}
  2. char foo() {...}.
据我所知,当对常量T进行调用时,我们解析为(1);对于非常量T,则解析为(2)。
  1. 这是正确的吗?
  2. 在此解析中调用了哪个规则?(参考标准很好,但简要摘要也会受到赞赏)
注:
  1. 我尝试通过Google搜索,但我得到的旧结果都是涉及const的其他重载解析案例。然而,链接到旧的SO实际上解释了上述问题,这显然是很好的。
  2. 重新阅读Stroustrup的《C ++编程语言》,第二版(“特别版”),字符串/ Cref示例在第11.12节,第296页。由于Stroustrup非常精确,答案可能在前面的章节中,但我没有看到在哪里。对Stroustrup章节的引用也非常欢迎(最好是第二版,因为这是我拥有的版本)。第10.2.6节介绍了const成员作为那些“不改变对象值”的成员,这暗示了答案,但对我来说并不是一个清晰的解析指令。

2
从高层次的角度来看,您可以考虑编译器将执行的转换。成员函数将被转换为:char foo(T const *this)char foo(T *this)(细节暂且不提)。 - David Rodríguez - dribeas
@dribeas - David Rodriguez:我明白了;对于指针类型的参数,const p 和 p 在重载决议中是有区别的,对吗?这确实给了一些直觉。 - gnometorule
我已经正确地重新格式化了您的问题。请花点时间阅读Markdown格式帮助 - Konrad Rudolph
3
额外的 T* / T const* 参数被称为“隐式对象参数”(实际上它是一个引用);我不明白为什么这应该是高级视图。虽然隐式对象参数与实际函数参数之间存在某些细微差别,但据我所知,大部分重载分辨率将它们视为相等的。请参见 [over.match.funcs]。 - dyp
根据 [over.match.funcs],隐式对象参数是一个引用。我指的不是必须传递某些内容以设置 this 指针的意义; 我指的是重载解析机制使用一个“虚构”的附加参数+参数。 - dyp
显示剩余4条评论
1个回答

11
在我手头的N3242(标准草案)中,第13.3.1段第4句话说:
隐式对象参数的类型对于没有ref-qualifier或使用& ref-qualifier声明的[非静态成员]函数是“lvalue引用到 cv X”,
这意味着隐式对象参数的类型,它出现在第一位,是一个“lvalue引用到 cv X ”,其中 X 是类,而 cv 是成员变量的cv限定符(即const或非const)。然后,重载解析继续进行。
要查看重载解析过程,请首先将两者列为“候选”函数,因为它们在正确的范围内并具有正确的名称。
const情况下,只有const成员函数可以进入下一步(称为“可行性”),因此它自动成为最佳选择。非const成员函数不可行,因为您无法将const引用转换为非const引用。
在非const情况下,const和non-const版本都是可行的,但非const版本更好,因为13.3.3.2段第3条规则的第五条规定如下:
如果标准转换序列S1比标准转换序列S2更好,则标准转换序列S1是更好的转换序列,其中...
S1和S2都是引用绑定,并且引用所指向的类型除了顶层cv限定符外相同, 并且由S2初始化的引用所引用的类型比由S1初始化的引用所引用的类型更多cv限定符。

你的解释很有道理,但是 (a) 引用应该继续吗?它似乎是 "if type is (...)",但好像少了 "then (...)";(b) 引用适用于 t成员函数,对吗?(引用说的只是函数。) - gnometorule
我看到你已经解决了(b)(谢谢);那么(a)呢?(或者告诉我为什么(a)不重要) - gnometorule
抱歉,我不理解。最近我添加了更多的上下文。基本上它的意思是,对于没有ref-qualifier声明的非静态成员函数(您的情况),隐式对象参数是对X的引用,具有函数声明时的任何cv状态。我没有看到任何未满足的条件语句。 - rmcclellan
是的..我在评论中错过了一种可能的引用绑定等级:派生到基础的转换。但这似乎与隐式对象参数无关:http://coliru.stacked-crooked.com/a/43afc78eabcf247c - dyp
gnometorule:抱歉,我觉得我的回答不够清晰。隐式对象参数的const属性(即标准术语中的cv限定符)与成员函数的const属性相同。我刚刚进行了编辑,希望这部分现在更加清晰明了。 - rmcclellan
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接