noob在这里。以下是我在书籍示例中遇到的类定义的片段:
double& operator[](int i);
double operator[](int i) const;
我的问题是:为什么这不模糊?编译项目文件时,编译器不会给出任何错误。
另外,在下面(想象AnyClass包含一个valarray<double>
对象,例如我想直接访问它):
AnyClass test;
cout << test[2]
编译器使用哪个版本?
答案 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
足以消除重载的歧义,这将有效地发挥作用。