如何为boost :: variant实现算术运算符,以便它支持不同的数字类型

时间:2015-02-05 16:31:46

标签: c++ boost boost-variant

例如,如果我有以下变体和static_visitor:

typedef boost::variant<long, int, float, double> DataType;

我希望这样做:

DataType x(1.2);
DataType y(100);
std::cout<<boost::apply_visitor(Multiply(), x, y)<<std::endl; // should return 120

有这样的访问者:

struct Multiply : public boost::static_visitor<DataType>
{
    template<typename T, typename U>
    DataType operator()(const T& a, const U& b) const
    {
        // what to do here??
    }

    template<typename T>
    DataType operator()(const T& a, const T& b) const
    {
        return a * b;
    }
};

如何在不必在Multiply访客中列出所有可能的类型组合的情况下执行此操作?

1 个答案:

答案 0 :(得分:2)

我的建议:不要在相同类型的特殊情况下,但在可乘性上:

struct Multiply : public boost::static_visitor<DataType> {
    template<typename T, typename U>
    static auto operator()(const T& a, const U& b) const
    -> decltype(DataType(a*b)){
        return a*b;
    }
    template<typename... Ts>
    static DataType operator()(const Ts... params) const {
        throw std::invalid_argument("can't multiply");
    }
};

的变化:

  • 没有任何组合的特殊外壳。
  • 对任何没有的组合投掷例外。
  • 现在static

使用表达式-SFINAE来决定。

但是,对于你的例子,它不会返回120,因为二进制浮点不能完全代表1.2。