鉴于以下代码:
class A
{
public:
A(): value( 0 ) {}
int* get()
{
return &value;
}
const int& get() const
{
return value;
}
private:
int value;
};
int main()
{
A a;
const int& ref_value = a.get();
}
导致以下编译错误:
prog.cpp: In function 'int main()':
prog.cpp:23:35: error: invalid conversion from 'int*' to 'int'
const int& ref_value = a.get();
^
似乎带有const修饰符的重载get()方法确实被完全忽略,编译器只看到它的非const定义。这是可以理解的,因为一个对象不是常数。一种解决方案是使 a 对象保持不变。虽然还有其他两个解决方案使代码可编译:
通过添加不同的名称或其他参数来更改const get()方法的签名。
int* get();
const int& get_changed() const; <-- this gets called
更改非const get()方法以返回引用而不是指针。
int& get(); <-- this gets called
const int& get() const;
虽然有
int* get();
const int& get() const;
我们遇到编译错误。
令我困惑的是所有这些行为背后的原因。
答案 0 :(得分:3)
原因是编译器无法根据不同的返回类型执行重载解析。
过载分辨率仅考虑功能签名。函数签名只包含函数名,参数和cv限定符 - 而不是返回类型。
答案 1 :(得分:3)
如果同一函数的const
和非const
重载具有相同的参数,则调用哪一个取决于{{1}上仅 你正在调用该函数的对象的ness。因此,在非const const
上调用必须调用非a
重载。
与此情况完全相同:
const
可以在非void foo(int *p);
void foo(const int *p);
int main()
{
int i;
const int ci;
foo(&i); // Calls the first overload
foo(&ci); // Calls the second overload
}
限定对象上调用const
- 限定函数 ,但这需要对#con;&#34;转换。如果超载不需要这样的转换(更好的匹配),那么它将是首选。