重载解析不正确,const 参数的值为 0

Incorrect overload resolution with value of const argument as 0

本文关键字:参数 const 不正确 重载      更新时间:2023-10-16

我有一个类B,其中包含两个重载函数int Set(B *);int Set(const A&);。类A需要一个构造函数参数unsigned char。当使用值为 0const unsigned char调用 Set 时,它被解析为Set(B*)而当传递的值不为零时,它会解析为 Set(const A&)(根据我的期望)。

重载分辨率在非常量unsigned char中预期有效,但在值设置为 0const unsigned char时失败。为什么?

以下代码说明了使用 const 和非 const 调用 Set 时的差异unsigned char

#include <iostream>
using namespace std;

class A{
  char m_byteValue;
public:
  A(unsigned char c) {
    m_byteValue = c;
  }
};

class B{
  int m_a;
public:
  B(){
    m_a = 2;
  }
  int Set(B *);
  int Set(const A&);
};
int B::Set(const A& v) {
  cout << "I am in the const ref functionn";
  return 0;
}
int B::Set(B* p) {
  cout << "I am in the pointer functionn";
  return 0;
}
int main(){
  const unsigned char a = 0;
  const unsigned char b = 1;
  unsigned char c = 0;
  unsigned char d = 1;
  B var;
  var.Set(a);
  var.Set(b);
  var.Set(c);
  var.Set(d);
  return 0;
}

输出(由 gcc 4.9.2 c++98 编译):演示 - 在 ideone c++ 5.1 上

I am in the pointer function // Why?
I am in the const ref function
I am in the const ref function
I am in the const ref function

标准之间的区别在这里:

C++98 [转换]

空指针常量是计算结果为零的整数类型的整数常量表达式 rvalue。

C++11 [会议]

空指针常量是值为零或 prvalue 类型为 std::nullptr_t 的整数文本。

const unsigned char a = 0;满足整型常量表达式的 C++98 定义。当然a不是右值,但似乎左值到右值的转换适用,并且仍然比用户定义的从unsigned charA的转换更匹配。

a不是字面意思,这就是C++11中行为不同的原因。

Clang 重现了错误,但幸运的是在编译过程中也给了你答案:

overloading_incorrect.cxx:41:13: warning: expression which evaluates
to zero treated as a null pointer constant of type 'B *'
[-Wnon-literal-null-conversion] 
var.Set(a);
        ^

正如 NathanOliver 在您的帖子中正确提到的那样,一旦使用 c++11 标准(将 -std=c++11 标志添加到编译器),这种行为就会消失。