1

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

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

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

AnyClass test;
cout << test[2]

编译器使用哪个版本?

4

4 回答 4

7

它不是模棱两可的,因为它const是签名的一部分,可用于重载解决方案。因此,如果您operator[]在非常量对象上使用,它会选择重载,const因为这是最具体的。如果你在 const 对象上使用它,它会选择重载,const因为这是唯一适用的。

于 2012-09-04T16:10:44.067 回答
1

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

这就是编译器解决歧义的方式。

于 2012-09-04T16:10:09.697 回答
1
AnyClass test;
const AnyClass const_test;
std::cout << test[2];       // calls operator[](int)
std::cout << const_test[2]; // calls operator[](int) const
于 2012-09-04T16:10:47.597 回答
1

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

#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);
}

这打印:

常量:你好
可变:你好

编译器将尽可能选择限制最少的重载。因此,如果您在过载char*时使用 a char*,它将选择它;但如果没有,编译器将决定将其强制转换为 aconst char*是可行的转换(显然,反之亦然)。

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

于 2012-09-04T16:16:58.723 回答