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

时间:2015-01-15 21:01:39

标签: c++ c++11 overloading

我有以下测试代码:

#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&) constvoid Comparison(CString const&) const(但不是两者),代码编译并选择非-const overload。

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

  1. 首先选择具有完全匹配参数的函数
  2. 接下来尝试了1级隐式转换
  3. 在这两种情况下,1&amp; 2是模棱两可的。有人可以解释一下吗?感谢。

1 个答案:

答案 0 :(得分:7)

对于类方法,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]中:

  

成员函数被认为有一个额外的参数,称为隐式对象参数,其中   表示已调用成员函数的对象。出于重载解析的目的,静态和非静态成员函数都有一个隐式对象参数,但构造函数没有。

     

对于非静态成员函数,隐式对象参数的类型为

     

- 对于没有引用限定符或使用&amp;而声明的函数的“对cv X的左值引用” REF-限定符

     对于用&amp;&amp ;;声明的函数,

- “对cv X的rvalue引用” REF-限定符

     

其中X是函数所属的类,cv是成员的cv资格   功能声明。 [示例:对于类X的const成员函数,假设为额外参数   有类型“引用const X”。 - 例子]

     

在重载解析期间,隐含的对象参数与​​其他参数无法区分。

这确定了我们考虑const TestBed& vs TestBed&的原因。然后,只需比较重载(1)(2)之间的转换序列。对于第二个参数,两个转换序列都相等,但对于第一个参数,(2)具有更好的转换序列(即Exact) - 这就是为什么它在没有歧义的情况下获胜。