21 Temmuz 2016 Perşembe

boost any

Giriş
Bu sınıf kendi içinde new ile alınan bir pointer tutuyor. Boost any type_erasure'a dayalıdır. Eskiden boost any kütüphanes move constructor'ı desteklemiyordu ancak artık destekliyor.

type metodu
Elimizde şöyle bir map olsun
map<std::string, boost::any> cols;
any_cast yapmadan typeid ile tip kontrol ediliyor ve daha sonra any_cast yapılıyor.
if (cols[key].type() == typeid(std::vector<int>)) {
  process(cols[key].any_cast<std::vector<int>>());
} else if (cols[key].type() == typeid(std::vector<double>)) {
  process(cols[key].any_cast<std::vector<double>>());
}
...
} else {
    throw std::runtime_error("Oops! Seems that I missed a type :-(");
}
Elimizde map yerine vector olsun
std::vector<boost::any> v_any;
Iterator ile dolaşarak tip kontrolü şöyle yapılır.
for(auto it = v_any.begin() ; it != v_any.end() ; ++it  ) {
  if (it->type() == typeid(class_1)){
    class_1 c1 = boost::any_cast< class_1 > (*it );
    ...
   }
}
boost::any nesnenin kopyasını alır
boost::any constructor içinde belirtilen nesnenin kopyasını alır. Şöyle görebiliriz.
class Base
{
public:
  template<typename T>
  void method(T& data)
  {
    methodImpl(boost::any(data));
  }

protected:
  virtual void methodImpl(boost::any& data) = 0;
};

class Derived : public Base
{
private:
  void methodImpl(boost::any& data)
  {
    Parameter& param = boost::any_cast<Parameter&>(data);
    // Change param attributes...
  }
};

int main()
{
  Derived derived;
  Parameter param;

  derived.method(param);
  // param hasn't changed...
}

boost::any_cast metodu - free style
any_cast yazısına taşıdım.

Başka alternatifler
Bu sınıfa daha güzel bir alternatif variant sınıflar. Şöyle yaparız.
typedef enum __VarType {
  V_INT,
  V_CHAR,
  V_FLOAT,
} VarType;

typedef struct __Var {
  VarType type;
  union {
    int i;
    char c;
    float f;
  };
} Var;

void var_init_int(Var *v, int i) {
  v->type = V_INT;
  v->i = i;
}

void var_init_char(Var *v, char c) {
  v->type = V_CHAR;
  v->c = c;
}

void var_init_float(Var *v, float f) {
  v->type = V_FLOAT;
  v->f = f;
}



Hiç yorum yok:

Yorum Gönder