Неоднозначность при перегрузке оператора приведения - PullRequest
1 голос
/ 28 февраля 2012

Рассмотрим пример кода ниже:

#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";
}

В строке 1 выполняется неявное приведение.Я понимаю, как в этом случае работает неявное приведение.Компилятор не выдает ошибок.

Но в строке 2 явное приведение объекта sample выполняется к объекту dummy.Но компилятор выдает следующую ошибку:

ошибка: вызов перегруженного `dummy (sample &) 'неоднозначен

note: кандидатами являются: dummy :: dummy (const dummy &)

примечание: dummy :: dummy (int)

Вопросы:

  1. Почему возникают эти ошибки?

  2. Я не понимаю значения сообщений об ошибках.Почему функции-кандидаты класса dummy упоминаются в ошибках?

1 Ответ

5 голосов
/ 28 февраля 2012

Линия:

d = (dummy)ob1

пытается сделать следующее:

  1. Построить dummy объект из obj1
  2. Назначить этот временный dummy объект d

Часть 1 - это то, что вызывает проблемы. Чтобы создать временный объект dummy, компилятор должен найти какой-то способ преобразования obj1 в тип, из которого можно построить dummy. Он находит, что есть два способа сделать это:

  1. Звоните operator int
  2. Звоните operator dummy

Вы не говорите ему, какую из этих двух альтернатив вы хотите использовать, и поэтому код неоднозначен.


Ваша проблема может быть воссоздана (с удалением посторонних частей) следующим образом:

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