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

voi*_*ter 8 c++ overloading c++11

我有以下测试代码:

#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");
}
Run Code Online (Sandbox Code Playgroud)

此代码无法编译,因为调用Comparison()是不明确的.我期待这种行为.

但是,当我进行任何一个Comparison()重载时const,如:void Comparison(std::string const&) constvoid Comparison(CString const&) const(但不是两者),代码编译并选择非const重载.

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

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

在这两种情况下,1和2都是模棱两可的.有人可以解释一下吗?谢谢.

Bar*_*rry 7

对于类方法,该this部分被视为是一个额外的参数.所以,如果你创建了CString一个const,那么就会设置重载:

Comparison(const TestBed&, CString const&) // (1)
Comparison(TestBed&, std::string const&)   // (2)
Run Code Online (Sandbox Code Playgroud)

对于(1),我们需要进行两次转换:const转化和转化CString.但是,对于(2),我们只需要进行一次转换:到std::string.因此,(2)是优选的.

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

Comparison(const TestBed&, const char*)  // (3)
Run Code Online (Sandbox Code Playgroud)

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


在[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) - 这就是为什么它没有歧义地获胜.