我想比较几种数值类型的两个变体。
#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);
}
在msvc上,这会引起警告。
这样安全吗? (aka在所有情况下都给出了预期的结果)
如果不能,那么如何安全地完成它?
答案 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。这样一来,您就可以在变体需要比较做正确的事情(即返回预期结果)时区分变体所持有的类型。