简体   繁体   English

为什么非const方法隐藏const重载?

[英]Why does non-const method hide const overload?

Given the code below: 给出以下代码:

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

results in the following compilation error: 导致以下编译错误:

prog.cpp: In function 'int main()':
prog.cpp:23:35: error: invalid conversion from 'int*' to 'int'
      const int& ref_value = a.get();
                                   ^

It seems that the overloaded get() method with const modifier does get ignored completely and the compiler sees only the non-const definition of it. 似乎带有const修饰符的重载get()方法确实会被完全忽略,并且编译器只能看到它的非const定义。 It is somehow understandable since the a object is not constant. 这是可以理解的,因为对象不是常数。 One solution would be to make the a object constant. 一个解决办法是让一个对象不变。 Though there are other two solutions that makes the code compileable: 尽管还有其他两种解决方案可以使代码可编译:

  1. Change the signature of the const get() method by different name or other parameters added. 通过使用其他名称或添加的其他参数来更改const get()方法的签名。

     int* get(); const int& get_changed() const; <-- this gets called 
  2. Change the non-const get() method to return a reference instead pointer. 更改非const get()方法以返回引用而不是指针。

     int& get(); <-- this gets called const int& get() const; 

though with 虽然与

int* get();
const int& get() const;

we have a compiler error. 我们有一个编译器错误。

What puzzles me is the reason behind all of these behavior. 让我感到困惑的是所有这些行为背后的原因。

The reason is that the compiler can't do overload resolution based on a different return type. 原因是编译器无法基于其他返回类型执行重载解析。

Only the function signature is taken into account for overload resolution. 对于重载解析,仅考虑功能签名。 And the function signature consists only of the function name, the parameters, and the cv qualifiers - not the return type. 而且,函数签名仅由函数名称,参数和cv限定符组成-而不是返回类型。

When you have both a const and non- const overload of the same function with the same parameters, which one gets called depends only on the const ness of the object on which you're invoking the function. 当你同时拥有一个const和非const使用相同的参数相同的功能,其中一个被调用的过载依赖于const上你调用函数的对象的湖。 So invoking on a non-const a must call the non- const overload. 所以调用一个非const a 必须调用非const过载。

It's exactly the same situation as this: 这是完全相同的情况:

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
}

A const -qualified function can be called on a non- const -qualified object, but that requires a "nonconst to const" conversion. const -qualified功能可以const上调用-qualified对象,但是这需要一个“非const成const”的转换。 If there's an overload which doesn't require such a conversion (is a better match), it will be preferred. 如果存在不需要这种转换的重载(更好的匹配),则将是首选。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM