如何在C++ 11中访问可能不存在的类型别名?

Rom*_*man 11 c++ templates c++11

我想写这样的东西:

template <class T>
using MyTypeOrTupple = typename std::conditional<has_member_type_MyType<T>::value,
                                                 typename T::MyType,
                                                 std::tuple<> >::type;
Run Code Online (Sandbox Code Playgroud)

我has_member_type_MyType使用https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector实现

然而,海湾合作委员会(4.8.4)仍然抱怨使用T::MyType何时MyType未定义T.有办法解决这个问题吗?

T.C*_*.C. 13

不要使用Wikibooks那种疯狂的东西.

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

template<class T> 
using MyTypeOrTuple = detected_or_t<std::tuple<>, MyType_t, T>;
Run Code Online (Sandbox Code Playgroud)

哪里detected_or_t是std::experimental::detected_or_t从图书馆基本面TS V2,并且可以实现如下:

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;
Run Code Online (Sandbox Code Playgroud)


Pio*_*cki 6

template <typename...>
struct voider { using type = void; };

template <typename... Ts>
using void_t = typename voider<Ts...>::type;

template <typename, typename = void_t<>>
struct MyTypeOrTupple { using type = std::tuple<>; };

template <typename T> 
struct MyTypeOrTupple<T, void_t<typename T::MyType>> { using type = typename T::MyType; };

template <typename T>
using MyTypeOrTupple_t = typename MyTypeOrTupple<T>::type;
Run Code Online (Sandbox Code Playgroud)

DEMO

  • @Roman见[this](http://stackoverflow.com/q/27687389/3953764)和[this](http://stackoverflow.com/q/25833356/3953764) (3认同)