違う名前でも取得したい
例えば、関数オブジェクトの戻り値型を定義する場合、result や result_type, もしくは、result_t 等、意味は同じでも別の名前で定義される可能性があります。
struct func1{ typedef int reuslt_type; /* ... */ }; struct func2{ typedef float result; // 名前は違っても意味は同じ /* ... */ };
これらは、定義する名前が違っていても意味としては同じです。
こんな感じで、名前が違っていても意味が同じものの取得を行いたかったのでコーディングしてみました。
#include <boost/static_assert.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/mpl/apply.hpp> #include <boost/mpl/lambda.hpp> #include <boost/mpl/vector.hpp> #include <boost/mpl/map.hpp> #include <boost/mpl/pair.hpp> #include <boost/mpl/find_if.hpp> #include <boost/mpl/has_xxx.hpp> #include <boost/mpl/identity.hpp> namespace mpl = boost::mpl; namespace detail{ template<typename Seq, typename Pred> struct find_if_map : mpl::second< typename mpl::deref< typename mpl::find_if< Seq, mpl::apply1< typename mpl::lambda<Pred>::type, mpl::first<mpl::_1> > >::type >::type > {}; BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator); template<typename T> struct element_iterator : mpl::identity<typename T::iterator>{}; BOOST_MPL_HAS_XXX_TRAIT_DEF(Iterator); template<typename T> struct element_Iterator : mpl::identity<typename T::Iterator>{}; BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator_type); template<typename T> struct element_iterator_type : mpl::identity<typename T::iterator_type>{}; typedef mpl::map< mpl::pair<has_iterator<mpl::_1>, element_iterator<mpl::_1> >, mpl::pair<has_Iterator<mpl::_1>, element_Iterator<mpl::_1> >, mpl::pair<has_iterator_type<mpl::_1>, element_iterator_type<mpl::_1> > > iterators_map; template<typename T> struct iterator_type : mpl::apply1< typename find_if_map<iterators_map, mpl::apply1<mpl::_1, T> >::type, T > {}; } // namespace detail using detail::iterator_type; struct hoge_iterator{ typedef int iterator; }; BOOST_MPL_ASSERT(( boost::is_same< iterator_type<hoge_iterator>::type, hoge_iterator::iterator > )); struct hoge_Iterator{ typedef float Iterator; }; BOOST_MPL_ASSERT(( boost::is_same< iterator_type<hoge_Iterator>::type, hoge_Iterator::Iterator > )); struct hoge_iterator_type{ typedef char iterator_type; }; BOOST_MPL_ASSERT(( boost::is_same< iterator_type<hoge_iterator_type>::type, hoge_iterator_type::iterator_type > ));
要は、mpl::map に登録されている first の条件に一致すれば、second を返すような処理を行っていだけです。
has_xxx と element_xxx の定義が多い気がするけど仕方ないか……。
注意
上記の例では問題がありませんが、基本的に『名前が違えば意味が違う』ことの方が多いので安易に使用するのは危険な気がします。
それを踏まえた上で使用する場合は、has_xxx と element_xxx の部分をもう少し厳密に考えたほうが安全だと思います。
[boost]
ver 1.45.0