2013-05-28 2 views
3

Неправильно ли перегружать глобальный оператор == и != для плавающих точек? Я использую быстрые плавающие точки в игре environement, и я думал об использовании нечеткого сравнения во всем мире, так как я не могу представить ситуацию, когда я не ожидаю, что очень близкие числа не будут равными.Глобальная перегрузка == и! = Для плавающих точек

Любые советы?

+0

Звучит неплохо, иди за ним. – andre

+0

Если каждый аспект игры должен относиться ко всем таким плавающим точкам, то я не вижу никаких проблем с ним. Просто дайте другим разработчикам понять, что происходит, поэтому они не смущаются позже. Если вы используете инкапсулированный float-объект, я бы, вероятно, просто добавил к нему метод, например 'fuzzyCompare()' или что-то еще. – crush

+1

Нет, это звучит не очень хорошо. Просто используйте обычную функцию, такую ​​как 'floatcompare (f1, f2)', когда вам нужно выборочное сравнение. – stardust

ответ

1

Другие сообщения упомянули технические проблемы, с другой точки зрения:

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

11

Вы не можете. Перегрузки операторов C++ должны включать по крайней мере один пользовательский тип.

И даже если бы вы могли, это была бы плохая идея. Пользователи ожидают, что равенство будет transitive, то есть если a == b и b == c, то a == c. Похоже, ваше нечеткое сравнение не было бы транзитивным.

+1

Он может использовать тип оболочки везде, где более или менее прозрачно действует как число с плавающей запятой. Но второй момент по-прежнему остается неприятным вопросом. Было бы слишком легко позволить некоторой стандартной библиотечной функции попытаться использовать их и вызвать UB. – aschepler

+0

Это следствие того, что мне все равно придется иметь дело. Транзитивность принимается с помощью общих вычислений. Но, как вы говорите, если это не поддерживается C++, нет причин обсуждать это. Я просто использую функцию FuzzyCompare (float x, float y) ;. –

0

Проблема заключается в том: если вы на самом деле могли бы сделать это, и в коде вы видели что-то вроде:

if (a == b) { 
    // more things... 
} 

вы знаете, если это применение регулярного сравнения или, скажем, fuzzyCompare() функцию? Чтобы различать и то, и другое, вам придется искать в коде, какой тип a и b ... Вы не сможете прочитать свой собственный код, не задавая себе много вопросов и, возможно, ссылаясь на множество переменных с их типами.

Это именно тот сценарий, в котором перегрузка оператора становится кошмаром, и причина, по которой ее злоупотребление приводило к ее отбрасыванию для таких языков, как Java.

Надеюсь, это поможет.

+0

Но тогда один вызывает стандартный контраргумент, который равен 'equals (a, b)' так же непрозрачен ... –

+0

Извините, @ Oli, я не понимаю, что вы имеете в виду. Можете ли вы уточнить? – Baltasarq

+0

Я имею в виду аргумент, что оператор перегружает скрыть информацию о том, что происходит. Это правда. Но тогда это также верно в отношении эквивалентного кода, написанного без перегрузок операторов (например, 'equals()' вместо 'operator ==', 'plus()' вместо 'operator +'). –