Boost.Variant に型指定でアクセスしたい
boost::variant
の要素にアクセスする場合,which()
メンバ関数で boost::variant
が保持している値の型を見てからアクセスするか static_visitor
でアクセスするかの二択が普通だと思うけれど,「which()
でアクセスするのはマジックナンバー増えるから嫌」「ちょっとアクセスするだけで static_visitor
を定義するのは大仰すぎる」ということで,型でアクセスできる関数がほしいなとなった.
ので,作ったみた.
戻り値型は boost::optional
で,boost::variant
が目的の型の値を保持していなければ boost::none
を返す.
#include <boost/variant/static_visitor.hpp> #include <boost/variant/apply_visitor.hpp> #include <boost/optional.hpp> template<class T> struct static_getter : public boost::static_visitor<boost::optional<T>> { typedef boost::optional<T> return_type; return_type operator()(T const& val) const { return val; } template<class U> return_type operator()(U const&) const { return boost::none; } }; template<class T, class Variant> inline boost::optional<T> get(Variant const& v) { return boost::apply_visitor(static_getter<T>{}, v); } #include <boost/variant/variant.hpp> #include <iostream> template<class O> void print_optional(O const& o) { if (o) { std::cout << *o << std::endl; } else { std::cout << "none\n"; } } int main() { boost::variant<int, double> v = 42; print_optional(get<int>(v)); // 42 print_optional(get<double>(v)); // none return 0; }
なんか調べてみたら type()
というメンバ関数があって,std::type_info
を返すらしいので,それ使うという手もありそう.