одинаковое сравнение разных числовых типов - PullRequest
2 голосов
/ 09 июля 2019

У меня есть два варианта нескольких числовых типов, которые я хотел бы сравнить.

#include <cstdint>
#include <variant>

using Value = std::variant< uint64_t, int64_t, bool, float, double>;

bool compare(Value l, Value r){
    return std::visit([](auto v1,auto v2){return v1<v2;},l,r);
}

https://godbolt.org/z/ULCfVk

Однако на msvc это вызывает предупреждения.

Это безопасно? (он же дает ожидаемые результаты при любых обстоятельствах)

Если нет, то как это можно сделать безопасно?

1 Ответ

2 голосов
/ 09 июля 2019

Это безопасно?

Зависит от того, что вы считаете "безопасным".Ваш код не включает неопределенное поведение или подобные вещи, но он может определенно привести к неожиданным результатам.Пример:

Value v1 = std::int64_t{std::numeric_limits<std::int64_t>::min()};
Value v2 = std::uint64_t{42};

// Isn't v1 < v2? This assertion will fire...
assert(compare(v1, v2));

Проблема здесь в том, что ваш универсальный посетитель (универсальная лямбда) не будет различать типы и с радостью сравнивает целочисленное значение со знаком с беззнаковым.Первый преобразуется во второй, получая большое значение, и сравнение возвращает значение true.

Если нет, то как это можно безопасно выполнить?

Вы можете добавить дополнительные перегрузкик объекту функции посетителя.Взгляните на overloaded оборудование здесь .Таким образом, вы различаете тип, который хранится в варианте, когда сравнение требует от него правильных действий (т. Е. Возвращает ожидаемый результат).

...