不同数字类型的相同比较

时间:2019-07-09 07:37:28

标签: c++ visual-c++ compare c++17 variant

我想比较几种数值类型的两个变体。

#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上,这会引起警告。

这样安全吗? (aka在所有情况下都给出了预期的结果)

如果不能,那么如何安全地完成它?

1 个答案:

答案 0 :(得分:2)

  

这样安全吗?

取决于您认为“安全”的内容。您的代码不涉及未定义的行为或此类事情,但是绝对可以导致意外的结果。示例:

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));

这里的问题是,您的全部访问者(通用lambda)将不会区分类型,而会愉快地将带符号整数值与无符号整数值进行比较。前者转换为后者,产生较大的值,并且比较返回true。

  

如果不能,那么如何安全地完成它?

您可以向访问者函数对象添加其他重载。看一下overloaded机制here。这样一来,您就可以在变体需要比较做正确的事情(即返回预期结果)时区分变体所持有的类型。