operator []歧义解决方案

时间:2012-09-04 16:08:33

标签: c++ class operator-overloading ambiguity containment

noob在这里。以下是我在书籍示例中遇到的类定义的片段:

double& operator[](int i);
double operator[](int i) const;

我的问题是:为什么这不模糊?编译项目文件时,编译器不会给出任何错误。 另外,在下面(想象AnyClass包含一个valarray<double>对象,例如我想直接访问它):

AnyClass test;
cout << test[2]

编译器使用哪个版本?

4 个答案:

答案 0 :(得分:7)

它不含糊,因为const是签名的一部分,可用于重载解析。因此,如果在非const对象上使用operator[],它会选择不带const的重载,因为这是最具体的一个。如果你在const对象上使用它,它会选择const的重载,因为这是唯一适用的。

答案 1 :(得分:1)

如果在const对象上调用,则会使用const版本,否则使用另一个版本。

这就是编译器解决模糊性的方法。

答案 2 :(得分:1)

AnyClass test;
const AnyClass const_test;
std::cout << test[2];       // calls operator[](int)
std::cout << const_test[2]; // calls operator[](int) const

答案 3 :(得分:1)

要理解这一点,您通常只需要意识到参数上的const足以消除呼叫的歧义:

#include <iostream>

void foo(char* ptr)
{
    std::cout << "mutable: " << ptr << std::endl;
}

void foo(const char* ptr)
{
    std::cout << "const: " << ptr << std::endl;
}

int main()
{
    const char* constHello = "hello";
    char mutableHello[] = "hello";
    foo(constHello);
    foo(mutableHello);
}

打印:

  

const:你好   可变:喂

编译器会选择限制性最小的重载。因此,如果您在char*超载时使用char*,则会选择它;但是如果没有,编译器将决定将它转换为const char*是一个可行的转换(反过来,显然不是真的)。​​

现在,非常简单的是所有方法都将this指针作为任何函数的第一个参数传递。为简单起见,隐藏此参数。方法末尾的const限定this参数。因为,正如我们刚才看到的那样,指针上的const足以消除重载的歧义,这将有效地发挥作用。