Когда использовать операторы преобразования? - PullRequest
0 голосов
/ 19 сентября 2011

Рассматривая следующий пример, строка int a = objT + 5; дает неоднозначное преобразование, которое обрабатывается двумя способами, используя явное приведение, которое, как мне кажется, не нужно, и заменяя использование операторов преобразования вместо функций-членов.и здесь у меня возникает вопрос: должны ли вы по-прежнему использовать операторы преобразования или нет?

class Testable {

public:
    Testable(int val = 0):x(val){}

    operator int() const  { return x; }
    operator double() const  { return x; }

    int toInt() { return x; }
    double toDouble() { return x; }

private:
    int x;
};

int main()
{
    Testable objT(10);

    // ambiguous conversion
    int a = objT + 5;

    // why to use explicit cast when
    // the conversion operator is for to handle
    // this automatically
    int b = static_cast<int>(objT) + 5;

    // member functions
    int c = objT.toInt() + 5;
}

Ответы [ 4 ]

2 голосов
/ 19 сентября 2011

Обратите внимание, что int d = objT; однозначно, как и double e = objT; Здесь компилятор может однозначно выбрать оператор преобразования из-за точного соответствия между типом левой части и типами возврата из этих операторов преобразования.

Неоднозначное преобразование получается из objT + 5 (также обратите внимание: long f = objT; также неоднозначно). Проблема в том, что вы забрали важную информацию, необходимую компилятору для бездумного выполнения устранения неоднозначности.

Проблема исчезнет, ​​если вы избавитесь от любого из этих операторов преобразования. Поскольку базовый элемент данных - int, я предлагаю избавиться от operator double().

0 голосов
/ 19 сентября 2011

Этот вопрос похож на мой, , возможно ли изменить приоритет операторов неявного преобразования .К сожалению, не существует удовлетворительного решения, не существует приоритета среди неявных преобразований.

Одним из решений является дополнительная перегрузка (и) для неоднозначной функции или оператора, в вашем случае это оператор + (const Testable &, int) и operator + (const Testable &, double).

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

Используйте неявное преобразование только тогда, когда выотчаянно нужно автоматическое преобразование в данный тип.Явные toInt, toDouble функции намного лучше, они проясняют код и не скрывают потенциальных ловушек.Используйте явное ключевое слово для унарных конструкторов, они блокируют неявное преобразование через этот конструктор.

И нет, неявное преобразование невозможно, даже если они являются операторами или конструкторами.Стандарт C ++ обязывает только 1 неявное преобразование быть в последовательности преобразования.

0 голосов
/ 19 сентября 2011

Вам не нужно неявное преобразование для удвоения.Вы всегда возвращаете десятичное значение, и компилятор может объединять несколько операторов неявного преобразования.

Если бы ваше частное свойство x типа int было double, я бы порекомендовал не использовать неявное преобразование в int, так как это привело бы к потере точности.

0 голосов
/ 19 сентября 2011

Для вашего конкретного случая вы можете просто обеспечить преобразование в double, поскольку оно имеет стандартное преобразование в int. Однако неявные преобразования часто приносят больше вреда, чем помощи. Если вы используете их, тогда избегайте преобразования как из int (ваш неявный конструктор), так и в int, который, я думаю, является источником вашей текущей проблемы.

...