我有一个项目使用std::variant
作为可变长度类型:
using Length = std::variant<int, long, float, double, Fraction>;
Fraction
类已经使大多数运算符超载。
我想创建像:
这样的算术运算符Length operator+ (Length lhs, Length rhs);
Length operator- (Length lhs, Length rhs);
Length operator* (Length lhs, Length rhs);
Length operator/ (Length lhs, Length rhs);
但也比较运营商:
Length operator== (Length lhs, Length rhs);
Length operator!= (Length lhs, Length rhs);
Length operator> (Length lhs, Length rhs);
Length operator>= (Length lhs, Length rhs);
Length operator< (Length lhs, Length rhs);
Length operator<= (Length lhs, Length rhs);
这是我用std::visit
方法完成工作的模式。
Length operator* (Length lhs, Length rhs)
{
Length res;
std::visit([&res, rhs](auto& left)
{
using T = std::remove_cv_t<std::remove_reference_t<decltype(left)>>;
if constexpr (std::is_same_v<T, int>)
{
std::visit([&res, left](auto& right)
{
using T = std::remove_cv_t<std::remove_reference_t<decltype(right)>>;
if constexpr (std::is_same_v<T, int>) { res = left * right; } else
if constexpr (std::is_same_v<T, long>) { res = left * right; } else
if constexpr (std::is_same_v<T, float>) { res = left * right; } else
if constexpr (std::is_same_v<T, double>) { res = left * right; } else
if constexpr (std::is_same_v<T, Fraction>) { res = left * right; }
},
rhs);
}
else
if constexpr (std::is_same_v<T, long>)
{
std::visit([&res, left](auto& right)
{
using T = std::remove_cv_t<std::remove_reference_t<decltype(right)>>;
if constexpr (std::is_same_v<T, int>) { res = left * right; } else
if constexpr (std::is_same_v<T, long>) { res = left * right; } else
if constexpr (std::is_same_v<T, float>) { res = left * right; } else
if constexpr (std::is_same_v<T, double>) { res = left * right; } else
if constexpr (std::is_same_v<T, Fraction>) { res = left * right; }
},
rhs);
}
else
if constexpr (std::is_same_v<T, float>)
{
std::visit([&res, left](auto& right)
{
using T = std::remove_cv_t<std::remove_reference_t<decltype(right)>>;
if constexpr (std::is_same_v<T, int>) { res = left * right; } else
if constexpr (std::is_same_v<T, long>) { res = left * right; } else
if constexpr (std::is_same_v<T, float>) { res = left * right; } else
if constexpr (std::is_same_v<T, double>) { res = left * right; } else
if constexpr (std::is_same_v<T, Fraction>) { res = left * right; }
},
rhs);
}
else
if constexpr (std::is_same_v<T, double>)
{
std::visit([&res, left](auto& right)
{
using T = std::remove_cv_t<std::remove_reference_t<decltype(right)>>;
if constexpr (std::is_same_v<T, int>) { res = left * right; } else
if constexpr (std::is_same_v<T, long>) { res = left * right; } else
if constexpr (std::is_same_v<T, float>) { res = left * right; } else
if constexpr (std::is_same_v<T, double>) { res = left * right; } else
if constexpr (std::is_same_v<T, Fraction>) { res = left * right; }
},
rhs);
}
else
if constexpr (std::is_same_v<T, Fraction>)
{
std::visit([&res, left](auto& right)
{
using T = std::remove_cv_t<std::remove_reference_t<decltype(right)>>;
if constexpr (std::is_same_v<T, int>) { res = left * right; } else
if constexpr (std::is_same_v<T, long>) { res = left * right; } else
if constexpr (std::is_same_v<T, float>) { res = left * right; } else
if constexpr (std::is_same_v<T, double>) { res = left * right; } else
if constexpr (std::is_same_v<T, Fraction>) { res = left * right; }
},
rhs);
}
},
lhs);
return res;
}
这是有效的,但这是多余的,非美观的,并且可能没有那么快做大型操作过程。
答案 0 :(得分:4)
由于您的操作数属于变体类型,因此它们只是visit:
Length operator* (Length lhs, Length rhs)
{
return std::visit([](auto const &l, auto const &r) -> Length {
return l * r;
}, lhs, rhs);
}
标准库已经为您执行了所需的逻辑。