如何简化 boost 变体的加号操作?
Posted
技术标签:
【中文标题】如何简化 boost 变体的加号操作?【英文标题】:How to simplify the plus action on boost variant? 【发布时间】:2016-06-27 23:44:19 【问题描述】:我有 boost 变体类型定义:
typedef boost::variant< bool, int, float, double> VariantType;
我想对其执行加/减/乘/除操作。以添加类为例。问题是如果在 VariantType 中添加新类型,例如 std::string,则必须使用新类型更新 Add 类。
struct Add : public boost::static_visitor<VariantType>
template <typename T>
T operator() (T a, T b) const
return a + b;
float operator() (int a, float b) const
return a + b;
float operator() (float a, int b) const
return a + b;
double operator() (int a, double b) const
return a + b;
double operator() (double a, int b) const
return a + b;
double operator() (float a, double b) const
return a + b;
double operator() (double a, float b) const
return a + b;
VariantType operator() (bool a, int b) const
throw std::invalid_argument("bool and int can't Plus");
VariantType operator() (bool a, float b) const
throw std::invalid_argument("bool and float can't Plus");
VariantType operator() (bool a, double b) const
throw std::invalid_argument("bool and double can't Plus");
VariantType operator() (int a, bool b) const
throw std::invalid_argument("int and bool can't Plus");
VariantType operator() (float a, bool b) const
throw std::invalid_argument("float and bool can't Plus");
VariantType operator() (double a, bool b) const
throw std::invalid_argument("double and bool can't Plus");
;
用法:
VariantType v1 = 1;
VariantType v2 = 2.1;
VariantType v3 = boost::apply_visitor(Add(), v1, v2);
cout<<boost::get<double>(v3)<<endl; //Print 2.2
GCC 版本为 4.8.2; boost版本是1.57.0; 如何简单地添加类?谢谢。
【问题讨论】:
【参考方案1】:只要让它成为一个多态函子:
Live On Coliru
#include <boost/variant.hpp>
#include <iostream>
using VariantType = boost::variant<int, float, double, bool>;
struct Add : public boost::static_visitor<VariantType>
template <typename T, typename U>
auto operator() (T a, U b) const -> decltype(a+b) return a + b;
template <typename T> VariantType operator()(bool, T) const throw std::invalid_argument("Can't to bool");
template <typename T> VariantType operator()(T, bool) const throw std::invalid_argument("Can't add bool");
VariantType operator()(bool,bool) const throw std::invalid_argument("Can't add bools");
;
int main()
std::cout << std::boolalpha;
VariantType specimens[] = int(42), 3.14f, 3.14, true ;
for (auto lhs : specimens)
for (auto rhs : specimens)
try
std::cout << lhs << " + " << rhs << " == " << boost::apply_visitor(Add, lhs, rhs) << "\n";
catch(std::exception const& e)
std::cout << lhs << " + " << rhs << " ==> " << e.what() << "\n";
打印:
42 + 42 == 84
42 + 3.14 == 45.14
42 + 3.14 == 45.14
42 + true ==> Can't add bool
3.14 + 42 == 45.14
3.14 + 3.14 == 6.28
3.14 + 3.14 == 6.28
3.14 + true ==> Can't add bool
3.14 + 42 == 45.14
3.14 + 3.14 == 6.28
3.14 + 3.14 == 6.28
3.14 + true ==> Can't add bool
true + 42 ==> Can't to bool
true + 3.14 ==> Can't to bool
true + 3.14 ==> Can't to bool
true + true ==> Can't add bools
【讨论】:
我刚刚添加了一个带有许多小修复/说明 /cc @DanielSchepler 的实时示例以上是关于如何简化 boost 变体的加号操作?的主要内容,如果未能解决你的问题,请参考以下文章