Почему в этом случае перегруженный оператор друга предпочтительнее оператора преобразования

StackOverflow https://stackoverflow.com/questions/2439402

Вопрос

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

Спасибо!

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;
      }
}
Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

0 > aa

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top