Reputation: 3812
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
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