, ,
struct tag_base { using base = void; };
struct tag1 : tag_base { using base = tag_base; };
struct tag2 : tag1 { using base = tag1; };
struct tag3 : tag1 { using base = tag1; };
...
template<class U>
struct tag_matcher
{
template<class V, class W = std::enable_if_t<std::is_same<U,V>::value> >
operator V();
};
template<typename F, typename T>
std::true_type match_tag_impl( decltype(F{}(tag_matcher<T>()))* );
template<typename F, typename T>
std::false_type match_tag_impl( ... );
template<typename F, typename T>
struct match_tag
{
using type = std::conditional_t< decltype(match_tag_impl<F,T>(0))::value,
T, typename match_tag<F, typename T::base>::type >;
};
template<typename F>
struct match_tag<F,void> { using type = void; };
template<typename F, typename T, typename U>
struct has_same_tag_overload:
std::is_same< typename match_tag<F,T>::type, typename match_tag<F,U>::type > {};
, , , , . ++ 11, ++ 03, .
update re ++ 03:
, tag_matcher, , ++ 03, , sfinae .
, , :
template<class U>
struct tag_matcher{};
#define MATCHME(TAG) template<class T> TAG( tag_matcher<T>, std::enable_if_t<std::is_same<T,TAG>::value>* = 0 )
struct tag_base { using base = void; MATCHME(tag_base); };
struct tag1 : tag_base { using base = tag_base; MATCHME(tag1); };