How to detect a type type alias?

Viewed 84

I can detect a member using the following template check:

template <typename T, typename = void>
struct hasMember : std::false_type {};
template <typename T>
struct hasMember<T, decltype((void)T::member, void())> : std::true_type {};

E.g. for:

class Test{
public:
   int member;
   using sometype = size_t; 
}

I could do:

if constexpr(hasMember<Test>)
{
   //do something
}

Now suppose I need a constexpr if that tells me if a class has a using definition. I.e. something that could detect that some class (e.g. test) has a using definition of some type. I.e. something like

if constexpr(hasSomeType<Test>)
{
     //do something
} 

Is this possible in c++17? How?

1 Answers

You can do that by using the same method as with the data member detection. Instead of using a data member, simply use a member type and void_t:

template <typename T, typename = void>
struct hasSomeType : std::false_type {};

template <typename T>
struct hasSomeType<T, std::void_t<typename T::member_type>> : std::true_type {};

Alternatively you can use the detection idiom:

template<typename T>
using member_type_t = typename T::member_type;

You can put any expression there using decltype.

Then, use the alias to perform the detection:

if constexpr (is_detected<member_type_t, Test>) {
    // ...
}

Of course, in C++20, all of this becomes one liners:

// requires a type
if constexpr (requires(Test) { typename Test::member_type; }) {

}

// requires a member
if constexpr (requires(Test t) { t.member; }) {

}

Live example

Related