MRB
MRB

Reputation: 3812

how to check if a type is defined by typedef or using in template parameters

I want to declare a member type that depend on the template parameter:

template< typename T >
struct bc_allocator_traits
{
public:
    using this_type = bc_allocator_traits;
    using allocator_type = T;
    using value_type = typename allocator_type::value_type;
    using pointer_type = typename allocator_type::pointer_type; 
...

In this example pointer_type depend on the template parameter(allocator_type). but defining pointer_type for template parameter is optional and if template parameter doesn't present this type, i want to use a default type like value_type*.

Is there any way to achieve this optional member type definition in my classes?

Upvotes: 3

Views: 2030

Answers (1)

T.C.
T.C.

Reputation: 137310

This is like the posterchild for void_t.

template<class ...>
using void_t = void;

// workaround for some compilers: 
// template<class...> struct voider { using type = void; }; 
// template<class... Args> using void_t = typename voider<Args...>::type;

template<class T, class = void>
struct pointer_type_or_default { 
    using type = typename T::value_type*;
};

template<class T>
struct pointer_type_or_default<T, void_t<typename T::pointer_type>> { 
    using type = typename T::pointer_type;
};

and then

using pointer_type = typename pointer_type_or_default<allocator_type>::type;

The idea is that the partial specialization is viable and used only if T::pointer_type is valid and denotes a type.

The workaround is needed for compilers not implementing the resolution to CWG 1558. This includes GCC up to 4.9.2 (the current trunk version compiles the alias template version correctly, see PR 63825), and apparently MSVC.

Upvotes: 12

Related Questions