Почему друг перегружен оператором предпочтительнее оператора преобразования в этом случае - PullRequest
0 голосов
/ 13 марта 2010

Привет, у меня есть такой код, я думаю, что и оператор перегруженного друга и оператор преобразования имеют похожую функцию.Но почему в этом случае вызывается перегруженный оператор?Какие правила?

Большое спасибо!

class A{

    double i;
public:
    A(int i):i(i) {}
    operator double () const { cout<<"conversion operator"<<endl;return i;}                            // a conversion operator
    friend bool operator>(int i, A  a);                            // a friend funcion of operator >
};

bool operator>(int i, A  a ){
    cout<<"Friend"<<endl;
    return i>a.i;
}
int main()
{
    A  aa(1);
     if (0 > aa){
         return 1;
      }
}

Ответы [ 4 ]

4 голосов
/ 13 марта 2010

Для вызова перегруженного operator> преобразование не требуется. Для вызова встроенного operator> необходимо одно преобразование (пользовательский оператор преобразования. Разрешение перегрузки предпочитает варианты с меньшим количеством необходимых преобразований, поэтому используется перегруженный operator>.

Обратите внимание, что если вы измените определение вашего перегруженного operator>, например:

friend bool operator>(double i, A  a);

вы получите ошибку компиляции, потому что и перегруженный operator>, и встроенный operator> потребуют одно преобразование, и компилятор не сможет устранить неоднозначность.

1 голос
/ 13 марта 2010

Я не утверждаю, что мой ответ поддерживается стандартами, но давайте подумаем об этом логически.

Когда вы нажмете эту строку:

0 > aa

У вас есть два варианта. Либо вы звоните по указанному оператору:

friend bool operator>(int i, A  a);

Что на 100% совместимо, или вы можете сделать два преобразования, чтобы добраться до пункта назначения! Какой бы вы выбрали?

0 голосов
/ 13 марта 2010

Он вызывается, потому что это точное совпадение в контексте выражения 0 > aa. На самом деле, трудно понять, как вы пришли к вопросу «почему». По логике можно было бы задать вопрос «почему», если бы в этом случае другу не позвонили .

Если вы измените выражение на 0.0 > aa, вызов станет неоднозначным, потому что путь нейтрона будет лучше, чем у другого.

0 голосов
/ 13 марта 2010

Если вы добавите оператор преобразования, тогда объект типа A может быть преобразован в двойной, если вы меньше всего этого ожидаете.

Хорошая программа не предоставляет возможности для случайного использования его классов, и оператор преобразования открывает возможность использования класса в целом ряде непреднамеренных ситуаций (обычно в ситуациях, когда вы ожидаете ошибку времени компиляции). не из-за автоматического преобразования типов).

В результате к операторам преобразования (и конструкторам с одним аргументом) следует относиться с некоторой осторожностью, поскольку компилятор может выполнять преобразование, когда вы меньше всего этого ожидаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...