
Scott Meyers wrote: <...>
This is passing a runtime parameter to f, but what I want to pass to f is a compile-time type -- the type to dynamically_cast to. The pointer I'm casting is fixed, so I can bind it into f when I create f. Am I just missing something?
Here is a modified version of Daniel's code to suit the case from your original post (seems it wasn't intended to be a complete solution but rather a tutorial on how to implement the recursively inlined iteration with the MPL). Regards, Tobias #include <iostream> #include <boost/mpl/vector.hpp> #include <boost/mpl/begin_end.hpp> #include <boost/mpl/next.hpp> #include <boost/mpl/deref.hpp> namespace mpl = boost::mpl; // a toy model namespace ast { class node { public: virtual ~node() { }; }; class expression_node : public node { }; class literal : public expression_node { }; class operator_node : public node { }; class unary_operator : public operator_node { }; class binary_operator : public operator_node { }; class statement_node : public node { }; class for_loop : public statement_node { }; } // a toy visitor struct ast_visitor { typedef mpl::vector<ast::expression_node, ast::operator_node> accepted_types; void operator()(ast::expression_node &) { std::cout << "got an expression_node" << std::endl; } void operator()(ast::operator_node &) { std::cout << "got an operator_node" << std::endl; } }; // visit facility namespace detail { template <class Last, class Visitor> bool visit(Last, Last, ast::node *, Visitor &) { throw "bummer"; } template <class First, class Last, class Visitor> bool visit(First, Last, ast::node * node, Visitor & v) { typedef typename mpl::deref<First>::type type; type * typed_node = dynamic_cast<type *>(node); if (! typed_node) detail::visit(typename mpl::next<First>::type(), Last(), node, v); else v(*typed_node); } } template<class Visitor> bool visit(ast::node * node, Visitor & with_visitor) { typedef typename Visitor::accepted_types seq; return detail::visit( typename mpl::begin<seq>::type() , typename mpl::end<seq>::type() , node, with_visitor ); } int main() { ast_visitor v; { ast::literal test; visit(& test, v); } { ast::unary_operator test; visit(& test, v); } { ast::binary_operator test; visit(& test, v); } { try { ast::for_loop test; visit(& test, v); } catch(...) { std::cout << "error handling works" << std::endl; } } return 0; }