[英]How does const modifier for member functions affect overload resolution?
我有以下测试代码:
#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
或void Comparison(CString const&) const
(但不是两者),代码编译并选择非const超载。
重载解析规则非常复杂,我还没有看到任何描述const
如何影响这种情况的东西。 我的理解是:
在这两种情况下,1和2都是模棱两可的。 有人可以解释一下吗? 谢谢。
对于类方法, this
部分被视为额外参数。 因此,如果您将CString
设为一个const,则会设置重载:
Comparison(const TestBed&, CString const&) // (1)
Comparison(TestBed&, std::string const&) // (2)
对于(1)
,我们需要进行两次转换: const
转换和转换为CString
。 但对于(2)
,我们只需要进行一次转换:到std::string
。 因此, (2)
是优选的。
我们可以通过添加为此进行一次转换的第三个函数来验证这this
:
Comparison(const TestBed&, const char*) // (3)
在这里,我们再次只有一个转换(在“第一个”参数中),因此重载集是不明确的。
在[over.match.funcs]中:
成员函数被认为有一个额外的参数,称为隐式对象参数,它表示已调用成员函数的对象。 出于重载解析的目的,静态和非静态成员函数都具有隐式对象参数,但构造函数不具有。
对于非静态成员函数,隐式对象参数的类型是
- 对于没有引用限定符或使用&ref-qualifier声明的函数的“对cv X的左值引用”
- 对于使用&& ref-qualifier声明的函数的“对cv X的rvalue引用”
其中X是函数所属的类,cv是成员函数声明的cv-qualification。 [示例:对于类X的const成员函数,假设额外参数具有类型“对const X的引用”。 - 末端的例子]
在重载解析期间,隐含的对象参数与其他参数无法区分。
这就证明了为什么我们考虑const TestBed&
vs TestBed&
。 然后只是比较重载(1)
和(2)
之间的转换序列。 对于第二个参数,两个转换序列都相等,但对于第一个参数, (2)
具有更好的转换序列(即Exact) - 这就是为什么它没有歧义地获胜。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.