Variant Sınıfı
variant Sınıfı yazısına taşıdım.
Visitor
Şu satırı dahil ederiz.
Örnek 1
İstersek bazı template tipleri için metod yazıp geri kalanını hep aynı yere yönlendirebiliriz. Şöyle yaparız.
Örnek 2
Functor return type tanımlanması isteyebilir. Örneğin tüm tiplere ++ işlemi yapmak istersek şöyle yaparız.
bool tipi için Add işlemini gerçekleştiremeyen bir polymorphic functor yazmak için şöyle yaparız.
Şöyle çağrılır.
Tüm nesnelerin somet_operation metodu olduğunu varsayarak şöyle yaparız.
variant Sınıfı yazısına taşıdım.
Visitor
Şu satırı dahil ederiz.
#include <boost/variant.hpp> 
Visitor Tanımlama
Visitor şöyle tanımlanır. Visitor variant içindeki tüp tipler için bir operator()(X) tanımlamalıdır. Yoksa derleme hatası alırız.struct as_int_visitor : boost::static_visitor<int> {
    int operator()(std::string const& s) const { return std::stoi(s); }
    int operator()(int i)                const { return i; }
};struct visitor : boost::static_visitor<>
{
  void operator()(const int& i) const { ... }
  void operator()(const std::string & str) const { ... }
};
Template Visitor Tanımlama
Template kullanan visitor şöyle tanımlanır.
Template kullanan visitor şöyle tanımlanır.
struct GetVector : public boost::static_visitor<double>
{
  template<typename T>
  double operator() (const T& v)
  {...}
};struct ADD {};
struct DEL {};
class MultiVisitor : public boost::static_visitor<void> {
  public:
    template <typename T, typename U>
    void operator()(T& t, const U& u) {
      t.visit(u);
    }
};
static MV const add = ADD();
static MV const del = DEL();
MultiVisitor mv;
for (TShapes& shape : tshapes) {
  boost::apply_visitor(mv, shape, add);
  boost::apply_visitor(mv, shape, del);
}
Örnek 1
İstersek bazı template tipleri için metod yazıp geri kalanını hep aynı yere yönlendirebiliriz. Şöyle yaparız.
struct IsNullThing {
  bool operator()(Null) const { return true; }
  template <typename T> bool operator()(T) const { return false; }
  template <typename... Ts> bool operator()(boost::variant<Ts...> const& v) const{
    return boost::apply_visitor(*this, v);
  }
 };IsNullThing isNullThing;
// and just call it
MyVariant v;
bool ok = isNullThing(v);Functor return type tanımlanması isteyebilir. Örneğin tüm tiplere ++ işlemi yapmak istersek şöyle yaparız.
namespace detail {
struct incrementer {
    template< typename T >
    void operator()(T& x) const { ++x; }
    typedef void result_type;
};
}
void incr(AnyIterator& ai)
{
  boost::apply_visitor(detail::incrementer(),ai);
}bool tipi için Add işlemini gerçekleştiremeyen bir polymorphic functor yazmak için şöyle yaparız.
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"); }
};using VariantType = boost::variant<int, float, double, bool>;
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Şöyle çağrılır.
boost::apply_visitor(some_visitor(), myvariant);int as_int(StringOrInt const& v) {
    return apply_visitor(as_int_visitor{}, v);
}for (int i = values.size()-1; i > 0; --i)
  std::cout << as_int(values[i]);Tüm nesnelerin somet_operation metodu olduğunu varsayarak şöyle yaparız.
boost::apply_visitor([](auto const& obj) { obj.some_operation(); }, v); 
 
Hiç yorum yok:
Yorum Gönder