2015-02-05 1 views
0

Например, если у меня есть следующий вариант и 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?

ответ

2

Мой совет: Не специального случая на том же типа, но на multiplyability:

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.

+0

благодарю вас за ответ, но что делает второй оператор() в вашем примере? – swang

+0

Второй оператор выбирается, когда первый отбрасывается SFINAE. И это просто исключает исключение во время выполнения. – Deduplicator

+0

Я вижу, но я думаю, что пример, который вы даете, не работает из коробки, я получил такие ошибки: вызов '(const Multiply) (long int &, double &)' неоднозначен. Однако я могу заставить его работать, изменив 2-го оператора на вариационный шаблон. Могу ли я изменить ваш ответ, чтобы исправить его? – swang

Смежные вопросы