Her Tip İle Çalışacak Visitor
Elimizde bir variant olsun. variant ile kullanılan her tip getIntegerValue() ve getString() metodlarına sahip olsun
Şöyle yaparız.
Variant içinde hiyerarşik nesnelerin bulunması mantıklı değil, ancak böyle bir senaryo varsayalım. Visitor ile ata sınıfa pointer elde etmek için şöyle yaparız.
Örnek
C++14 ile şöyle yaparız.
Şöyle yaparız.
Önce bir ata sınıf tanımlarız.
Elimizde bir variant olsun. variant ile kullanılan her tip getIntegerValue() ve getString() metodlarına sahip olsun
typedef boost::variant <...,...> MyVar;
Her tip ile çalışacak bir template visitor için şöyle yaparız.struct MyVisitor : boost::static_visitor<void>
{
template <typename T>
void operator()(T& x) const
{
x.getIntegerValue());
x.getString());
}
};
Şöyle yaparız.MyVar variant = ...
MyVisitor visitor;
boost::apply_visitor (visitor, variant);
Bir Tip İle Çalışacak VisitorŞöyle yaparız.
template<typename T>
class converter_visitor : public boost::static_visitor<>
{
public:
std::vector<T>& vec;
converter_visitor(std::vector<T>& r) : vec(r) {}
// only push back values of specific types...
void operator()(const T& u) const {
vec.push_back(u);
}
// ignore other types...
void operator()(...) const {}
};
Bu visitor'ı yaratmak için şöyle yaparız.template<typename T>
converter_visitor<T> make_visitor(std::vector<T>& r)
{
return converter_visitor<T>(r);
}
Şöyle yaparız.template<typename T,typename U>
void filter(std::vector<T>& result,const U& var) {
boost::apply_visitor( make_visitor(result), var );
}
template<typename T,typename U>
void filter(std::vector<T>& result,const std::vector<U>& cont) {
std::for_each(cont.begin(),cont.end(),[&](const U& c) {
filter(result,c);
});
}
Şöyle yaparız._vec_var v1;
v1.push_back(11);
v1.push_back(13);
v1.push_back("see ya");
std::vector<int> result;
filter(result,vv);
Kalıtım ile Çalışacak VisitorVariant içinde hiyerarşik nesnelerin bulunması mantıklı değil, ancak böyle bir senaryo varsayalım. Visitor ile ata sınıfa pointer elde etmek için şöyle yaparız.
template<class Base>
struct poly_ptr_t:boost::static_visitor<Base*> {
template<class T>
Base* operator()(T& t)const { return std::addressof(t); }
template<class...Ts>
Base* operator[](boost::variant<Ts...>& v) const {
return boost::apply_visitor( *this, v );
}
template<class...Ts>
Base const* operator[](boost::variant<Ts...> const& v) const {
return boost::apply_visitor( *this, v );
}
};
Visitor'ın sonucunu kullanarak virtual metod çağırmak için şöyle yaparız.poly_ptr_t<Polygon> as_polygon;
int main() {
boost::variant<Triangle, Rectangle> u(Triangle{});
as_polygon[u]->set_values(x,y);
}
Generic Lambda VisitorÖrnek
C++14 ile şöyle yaparız.
boost::apply_visitor([](auto& x){
x.getIntegerValue());
x.getString());
}, variant);
ÖrnekŞöyle yaparız.
boost::apply_visitor( [](auto& e){...}, variant);
Visitor ve KalıtımÖnce bir ata sınıf tanımlarız.
template<class Derived, typename T>
struct BaseVisitor : public boost::static_visitor<T> {
using typename boost::static_visitor<T>::result_type;
Derived & derived() { return static_cast<Derived &>(*this); }
result_type operator()(const NextVar& n) {
return n.apply_visitor( derived() );
}
template<int I>
result_type operator()(const A<I>& a) {
return derived().visit(a);
}
};
Daha sonra kalıtan sınıfı yazarız. Şöyle yaparız.struct PrintVisitor : public BaseVisitor<PrintVisitor, std::string> {
template<int I>
std::string visit(const A<I>& a) {
return std::to_string(a.value);
}
};
Hiç yorum yok:
Yorum Gönder