私はオープン型切り替えを自分の小さな努力に置き換えました(私はそれを動作させることができませんでした.boost-variantでもすべて組み込まれています):
namespace visitor_galore // this is my make-shift replacement for typeswitch (I couldn't find it/make it work)
{
template<typename T, class...Fs> struct visitor_t;
template<typename T, class F1, class...Fs>
struct visitor_t<T, F1, Fs...> : F1, visitor_t<T, Fs...>::type {
typedef visitor_t type;
visitor_t(F1 head, Fs...tail) : F1(head), visitor_t<T, Fs...>::type(tail...) {}
using F1::operator();
using visitor_t<T, Fs...>::type::operator();
};
template<typename T, class F> struct visitor_t<T, F> : F, boost::static_visitor<T> {
typedef visitor_t type;
visitor_t(F f) : F(f) {}
using F::operator();
};
template<typename T=void, class...Fs>
typename visitor_t<T, Fs...>::type make_visitor(Fs...x) { return {x...}; }
}
using visitor_galore::make_visitor;
これがどのように使用されているかを確認するには、次の例をご覧くださいast_pp.cpp
。
void pretty_print(expression_incdec const& exp)
{
boost::apply_visitor(
make_visitor(
[&exp](inc_dec_op_preinc const& op) { std::cout << "++"; pretty_print(exp.variable); },
[&exp](inc_dec_op_predec const& op) { std::cout << "--"; pretty_print(exp.variable); },
[&exp](inc_dec_op_postinc const& op) { pretty_print(exp.variable); std::cout << "++"; },
[&exp](inc_dec_op_postdec const& op) { pretty_print(exp.variable); std::cout << "--"; }
)
, exp.operatur);
}
ボーナスブランチ内のすべてのタイプをリストすることにあまり関心がない場合、たとえば、すべてデフォルトで同じフリー関数 (またはオーバーロード) を呼び出すため、ポリモーフィック ビジターを使用できます。
static const struct pretty_print_visitor_ : boost::static_visitor<>
{
template<typename T>
void operator ()(T const& v) const { pretty_print(v); }
} pretty_print_visitor;
たとえば、次の 24 のブランチを置き換えることができますexpression&
。
boost::apply_visitor(
make_visitor(
[](expression_binop const& exp) { pretty_print(exp); },
[](expression_unop const& exp) { pretty_print(exp); },
[](expression_integer_constant const& exp) { pretty_print(exp); },
[](expression_character_constant const& exp) { pretty_print(exp); },
[](expression_string_constant const& exp) { pretty_print(exp); },
[](expression_boolean_constant const& exp) { pretty_print(exp); },
[](expression_null const& exp) { pretty_print(exp); },
[](expression_this const& exp) { pretty_print(exp); },
[](expression_static_invoke const& exp) { pretty_print(exp); },
[](expression_non_static_invoke const& exp) { pretty_print(exp); },
[](expression_simple_invoke const& exp) { pretty_print(exp); },
[](expression_ambiguous_invoke const& exp) { pretty_print(exp); },
[](expression_new const& exp) { pretty_print(exp); },
[](expression_new_array const& exp) { pretty_print(exp); },
[](expression_lvalue const& exp) { pretty_print(exp); },
[](expression_assignment const& exp) { pretty_print(exp); },
[](expression_incdec const& exp) { pretty_print(exp); },
[](expression_cast const& exp) { pretty_print(exp); },
[](expression_ambiguous_cast const& exp) { pretty_print(exp); },
[](expression_instance_of const& exp) { pretty_print(exp); },
[](expression_parentheses const& exp) { pretty_print(exp); },
[](lvalue_non_static_field const& exp) { pretty_print(exp); },
[](lvalue_array const& exp) { pretty_print(exp); },
[](lvalue_ambiguous_name const& exp) { pretty_print(exp); }
)
, exp);
簡単な方法で
boost::apply_visitor(pretty_print_visitor, exp);