C++ 为什么用'int*Get()'代替'const int&;得到()`?

C++ 为什么用'int*Get()'代替'const int&;得到()`?,c++,c++11,overload-resolution,C++,C++11,Overload Resolution,我有一个类B,它有两个方法,一个返回指向成员变量的指针,另一个返回对变量的常量引用 我尝试调用这些方法。在调用期间,我将返回值存储到相应的返回类型中 我希望适当的返回类型最终会调用适当的方法,但我得到一个编译错误,它说: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive] const int& refval2 = b.Get(); ` 错误:从“int*”到“int”[-fppermissive]的转换无效 cons

我有一个类
B
,它有两个方法,一个返回指向成员变量的指针,另一个返回对变量的常量引用

我尝试调用这些方法。在调用期间,我将返回值存储到相应的返回类型中

我希望适当的返回类型最终会调用适当的方法,但我得到一个编译错误,它说:

error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive] const int& refval2 = b.Get(); ` 错误:从“int*”到“int”[-fppermissive]的转换无效 const int&refval2=b.Get()` 这是我的密码:

#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(); 
}
#包括
B类{
公众:
int*Get(){
返回&x;
}
常量int&Get()常量{
返回x;
}
私人:
int x=0;
};
int main(){
B B;
const int&refval2=b.Get();
int*pval2=b.Get();
}
,在中不考虑它

通常,其参数与参数最匹配的候选函数是被调用的函数

对于非静态成员函数调用,要调用的对象的类型也包括。有两个
Get()
,一个是常量,一个是非常量。对于
b.Get()
,非常量
Get()
是完全匹配的;要调用常量
Get()
,必须将对象
b
转换为
const
。然后非常量一方获胜,然后编译器将尝试将返回的
int*
转换为
const int&
,但失败

所以


问题是编译器认为这两个Get()函数是相同的。如果创建两个相同的函数,但返回类型不同,编译器不知道要使用哪个函数。要解决此问题,请更改一个或两个Get()函数的名称;说GetXPtr()和GetX()

为什么调用
int*Get()
而不是
const int&Get()

是一个
const
成员函数

发件人:

如果成员函数声明为
const
,则此
的类型为
const X*

但是,你声明:

B b;

作为non-
const
调用non-
const
函数
int*Get()
。因此,不考虑作为已应答返回类型的错误。

。因此,我看到了3种可能的解决方案:

1将其作为功能签名的一部分:

class B {
public:
   void Get( int *&refptr );
   void Get( int &refval ) const;
};

int main(){
  B b;
  int refval2 = 0;
  b.Get( refval2 ); 
  int* pval2 = nullptr;
  b.Get( pval2 ); 
}
但这会产生非常难看的代码,所以最好使用方法2或3-

2使用不同的函数名,这很明显

3使用忽略的参数:

class B {
public:
   int *Get( nullptr_t );
   const int &Get() const;
};

int main(){
  B b;
  const int &refval2 = b.Get();
  int* pval2 = b.Get( nullptr ); 
}
有两件事

  • 重载解析中不考虑返回类型
  • 在过载分辨率中考虑了方法的常数

  • 如果在第二种方法中删除const,编译器会抱怨模糊性。在选择要调用的重载函数时,不使用返回类型。是否有一种方法可以确保调用正确的函数?C++的规则调用了“正确”函数,但返回类型是错误的。我将重命名为“代码> GETPrTE())<代码>,另一个是

    Get
    。如果我可以问一下,当接收端是
    const int&
    时,为什么选择
    int*Get()
    ?@codekaizer:
    b
    是非常量的,所以总是调用非常量
    Get
    cb
    是const,因此总是调用const
    Get
    。它取决于包含成员的类的类型,而不是返回值。@MooingDuck,我同意。有道理。请允许我问最后一个问题。我在标准的over.load或over.match.best部分没有看到它。这是在另一节中指定的,其中匹配是基于对象
    常量的吗?好了,现在一切都有意义了。谢谢@MooingDuck提供的代码片段。编译器实际上知道它要使用哪个函数,但不能,因为返回类型错误。备选方案:代理返回对象:@MooingDuck这是你的主意,你应该提交自己的答案。@Slava:haha我也这么想。上升。Mooing Duck:我发现代理类也很有趣。@Slava:这是解决问题的另一种选择,但与“为什么调用int而不是const int?”没有直接关系,所以问题是他为什么得到这些结果。
    
    class B {
    public:
       void Get( int *&refptr );
       void Get( int &refval ) const;
    };
    
    int main(){
      B b;
      int refval2 = 0;
      b.Get( refval2 ); 
      int* pval2 = nullptr;
      b.Get( pval2 ); 
    }
    
    class B {
    public:
       int *Get( nullptr_t );
       const int &Get() const;
    };
    
    int main(){
      B b;
      const int &refval2 = b.Get();
      int* pval2 = b.Get( nullptr ); 
    }