Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access a possibly unexisting type-alias in C++11?

I would like to write something like this:

template <class T>
using MyTypeOrTupple = typename std::conditional<has_member_type_MyType<T>::value,
                                                 typename T::MyType,
                                                 std::tuple<> >::type;

I implemented has_member_type_MyType using https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector

However, GCC (4.8.4) still complains about using T::MyType when MyType is not defined in T. Is there a way to solve this?

like image 337
Roman Avatar asked Aug 14 '15 10:08

Roman


1 Answers

Do not use that crazy thing from Wikibooks.

template <class T>
using MyType_t = typename T::MyType;

template<class T> 
using MyTypeOrTuple = detected_or_t<std::tuple<>, MyType_t, T>;

Where detected_or_t is std::experimental::detected_or_t from library fundamentals TS v2, and can be implemented as follows:

namespace detail {

    template<class...> struct voidify { using type = void; };
    template<class...Ts> using void_t = typename voidify<Ts...>::type;

    template <class Default, class AlwaysVoid,
              template<class...> class Op, class... Args>
    struct detector {
      using value_t = std::false_type;
      using type = Default;
    };

    template <class Default, template<class...> class Op, class... Args>
    struct detector<Default, void_t<Op<Args...>>, Op, Args...> {
      using value_t = std::true_type;
      using type = Op<Args...>;
    };

} // namespace detail

template <class Default, template<class...> class Op, class... Args>
using detected_or = detail::detector<Default, void, Op, Args...>;

template< class Default, template<class...> class Op, class... Args >
using detected_or_t = typename detected_or<Default, Op, Args...>::type;
like image 77
T.C. Avatar answered Oct 02 '22 18:10

T.C.