2015 обновление: Или, если вы хотите сохранить возможность преобразования с помощью (double)obj
синтаксиса вместо этого синтаксиса obj.to_double()
, сделать функцию преобразования explicit
предваряя его с этим ключевым словом , Для преобразования в триггер требуется явное преобразование. Лично я предпочитаю синтаксис .to_double
, если только конверсия не будет равна bool
, потому что в этом случае преобразование используется if(obj)
, даже если оно равно explicit
, и это значительно читаемо, чем if(obj.to_bool())
, на мой взгляд.
Опустите оператор преобразования. Это вызовет проблемы на всем пути. Есть функция, например
to_double()
Или похоже, что возвращает двойное значение и вызывает эту функцию явно, чтобы получить двойной.
Для решаемой задачи, есть такая проблема:
obj >= 10
Рассмотрим это выражение. Встроенный оператор сопоставляет первый аргумент с помощью определенной пользователем последовательности преобразования для вашего типа, используя оператор преобразования long double(). Но ваша функция соответствует второму аргументу стандартной последовательностью преобразования от int до long double (интегральной для преобразования с плавающей запятой).Он всегда неоднозначен, когда есть конверсии для двух аргументов, но не по крайней мере один аргумент, который может быть преобразован лучше, в то время как остальные аргументы не преобразуются хуже для одного вызова. В вашем случае встроенный один лучше соответствует второму аргументу, но в первую очередь хуже, но ваша функция лучше соответствует первому аргументу, а вторая хуже.
Это сбивает с толку, так вот некоторые примеры (преобразования из полукокса в Int называются акции, которые лучше, чем преобразования из полукокса в нечто иное, чем INT, который называется преобразование):
void f(int, int);
void f(long, long);
f('a', 'a');
Вызова первая версия. Потому что все аргументы для первого могут быть преобразованы лучше. Равным образом, следующее будет по-прежнему называют первое:
void f(int, long);
void f(long, long);
f('a', 'a');
Поскольку первой может быть превращены лучше, а второй не конвертируются хуже. Но следующее является неоднозначным:
void f(char, long);
void f(int, char);
f('a', 'a'); // ambiguous
Это более интересно в этом случае. Первая версия принимает первый аргумент точным соответствием. Вторая версия принимает второй аргумент точным соответствием. Но обе версии не согласны с их другим аргументом, по крайней мере, одинаково хорошо. Первая версия требует преобразования для второго аргумента, а для второй версии требуется продвижение по аргументу. Таким образом, несмотря на то, что продвижение лучше конверсии, вызов второй версии выходит из строя.
Это очень похоже на ваш случай выше. Несмотря на то, что стандартная последовательность преобразования (преобразование из int/float/double to long double) является лучше, чем пользовательская последовательность преобразований (преобразование из MyClass в long double), ваша версия оператора не выбрана, потому что ваш другой параметр (long double) требует преобразования из аргумента, который хуже, чем того требует встроенный оператор для этого аргумента (идеальное совпадение).
Разрешение перегрузки является сложным вопросом на C++, поэтому невозможно запомнить все тонкие правила в нем. Но получение приблизительного плана вполне возможно. Надеюсь, это поможет вам.
Извините, я имел в виду длинный двойной везде. – tunnuz