9 Kasım 2017 Perşembe

variant apply_visitor metodu

apply_visitor overload metodları
İmzası şöyle. İkinci overload'un tek farkı visitor'ın const olması. n tane variant alabilir.
template<typename MultiVisitor, typename Variant1, typename Variant2, typename Variant3> 
typename MultiVisitor::result_type OR decltype(auto) 
  apply_visitor(MultiVisitor & visitor, Variant1 & operand1, 
                Variant2 & operand2, Variant3 & operand3, ... other_operands);

template<typename MultiVisitor, typename Variant1, typename Variant2, typename Variant3> 
typename MultiVisitor::result_type OR decltype(auto) 
  apply_visitor(const MultiVisitor & visitor, Variant1 & operand1, 
                Variant2 & operand2, Variant3 & operand3, ... other_operands);
Açıklaması şöyle
Overloads accepting three or more operands invoke the function call operator of the given visitor on the content of the given variant operands. ... Those functions are actually defined in a header boost/variant/multivisitors.hpp ... That header must be manually included if multi visitors are meant for use.
Örnek
Elimizde 3 parametre kabul eden bir visitor olsun.
typedef boost::variant<double, std::string> term_t;

class plus_visitor : public boost::static_visitor<term_t> {
public:
  term_t operator()(double lhs, double rhs, double x) const{
    return {lhs + rhs + x};
  }
  term_t operator()(double lhs, std::string rhs, double x) const{
    return {lhs + std::stoi(rhs) + x};
  }
  term_t operator()(std::string lhs, double rhs, double x) const{
    return operator()(rhs, lhs, x);
  }
  term_t operator()(std::string lhs, std::string rhs, double x) const{
    return std::stoi(lhs) + std::stoi(rhs) + x;
  }
};
visitor'a 3 tane variant geçmek için şöyle yaparız.
term_t rhs {"10"};
term_t lhs {"3"};
term_t x {3.0};
term_t res = boost::apply_visitor(plus_visitor(), lhs, rhs, x);
Örnek
Elimizde iki variant olsun.
typedef boost::variant<std::string, int, double> V1;
typedef boost::variant<int, double> V2;
V1 input = 42;
V2 output = convert_variant<V2>(input);
Bir variant'ı diğerine çevirmek için şöyle yaparız.
template <typename R, typename A> R convert_variant(A const& arg) {
  return boost::apply_visitor([](auto const& v) -> R {
    if constexpr (std::is_convertible_v<decltype(v), R>)
      return v;
    else
      throw std::runtime_error("bad conversion");
  } , arg);
}


Hiç yorum yok:

Yorum Gönder