Search code examples
c++c++11overload-resolution

Why is the `int* Get()` called insted of `const int& Get()`?


I have a class B that has two methods, where one returns a pointer to a member variable and the other returns a const reference to the variable.

I try to call those methods. During the calls, I store the return values to respective return types.

I was expecting the appropriate return types would end up calling the appropriate methods, but I get a compilation error saying:

error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
   const int& refval2 =  b.Get(); `

Here is my code:

#include <iostream>
class B{
public:
  int* Get(){
    return &x_;
  }
  const int & Get() const{
    return x_;
  }

private:
  int x_ = 0;
};

int main(){
  B b;
  const int& refval2 =  b.Get(); 
  int* pval2 =  b.Get(); 
}

Solution

  • Return type is not part of function signature, it's not considered in overload resolution.

    In general, the candidate function whose parameters match the arguments most closely is the one that is called.

    For non-static member function call, the type of the object to be called on involves too. There're two Get(), one is const and one is non-const. For b.Get();, the non-const Get() is an exact match; for the const Get() to be called the object b has to be converted to const. Then the non-const one wins, after that the compiler will try to convert the returned int* to const int& and fails.

    So

    B b;
    int* pval2 =  b.Get();          // call to non-const Get()
    
    const B cb;
    const int& refval2 =  cb.Get(); // call to const Get()