重载演员操作时的歧义

时间:2012-02-28 05:20:03

标签: c++ operator-overloading typecast-operator

请考虑以下示例代码:

#include <iostream>

using namespace std;

class dummy
{
   private:
      int y;

   public:
      dummy(int b = 0) : y(b) {
      }

      friend ostream& operator<<(ostream& os, const dummy& obj);
};

ostream& operator<<(ostream& os, const dummy& obj)
{
   os << obj.y;
   return os;
}

class sample
{
   private:
      int x;

   public:
      sample(int a = 0) : x(a)
      {
      }

      operator dummy()
      {
         dummy d(100);
         return d;
      }

      operator int()
      {
         return x;
      }
};

int main()
{
   sample ob1(5);
   dummy d;

   //d = ob1; //Line1  
   d = (dummy)ob1; //Line2

   cout << d << "\n";
}

在Line1中,完成了隐式转换。我理解隐式转换在这种情况下是如何工作的。编译器没有错误。

但是在Line2中,对sample对象进行了dummy对象的显式转换。但编译器会出现以下错误。

  

错误:调用重载的`dummy(sample&amp;)'是不明确的

     

注意:候选人是:dummy :: dummy(const dummy&amp;)

     

注意:dummy :: dummy(int)

问题:

  1. 为什么会出现这些错误?

  2. 我不明白错误信息的含义。为什么错误中提到dummy类的候选函数?

1 个答案:

答案 0 :(得分:5)

该行:

d = (dummy)ob1

尝试执行以下操作:

  1. dummy
  2. 构建obj1对象
  3. 将该临时dummy对象分配给d
  4. 第1部分是导致问题的原因。要构造临时dummy对象,编译器必须搜索某种方式将obj1转换为可以构造dummy的类型。它发现有两种方法可以做到这一点:

    1. 致电operator int
    2. 致电operator dummy
    3. 你没有告诉它你想要它采用哪两个替代方案,因此代码含糊不清。


      您的问题可以重新创建(删除无关部分),如下所示:

      struct t_1 {};
      struct t_2 {};
      struct sample {
          operator t_1() const{ return t_1(); }
          operator t_2() const{ return t_2(); }
      };
      void f(t_1) {}
      void f(t_2) {}
      int main() {
          sample obj1;
          //overload resolution will fail
          //disambiguate with f(obj1.operator t_1()) or f(obj1.operator t_2())
          f(obj1);
      }