Thursday, October 20, 2011

Оно работает o_O

Решил тут запилить паттерн Visitor с блэкдже использованием std::shared_ptr:
#include <memory>
#include <type_traits>

...

struct Node : public std::enable_shared_from_this<Node> {
    virtual ~Node() {}
    virtual void accept(Visitor&) = 0;
};

#define DEFINE_ACCEPT_METHOD \
    virtual void accept(Visitor& v) { \
        v.visit(std::static_pointer_cast<std::remove_pointer<decltype(this)>::type>(shared_from_this())); \
    }

struct SomeNode : public Node {  
    ...
   DEFINE_ACCEPT_METHOD;
    ...
};
Но на самом деле макросы - зло. В данном случае можно обойтись безо всякой магии, просто заюзав CRTP ещё раз:
template <class NodeType>                                                                                       
struct VisitableNode : public Node {
    virtual void accept(Visitor& v) {
        v.visit(std::static_pointer_cast<NodeType>(shared_from_this()));
    }
};

struct SomeNode : public VisitableNode<SomeNode> { 
    ... 
};