In a type like the unspecialized template struct pointer_traits
(i.e. template <class Ptr> struct pointer_traits
), there exists a member alias template rebind
that is defined to be Ptr::rebind<U>
, if it exists, or some other type otherwise. Though I have seen a few answers on checking whether a certain member exists, how does one implement a "conditional" alias template like pointer_traits::rebind
? That is, as if by the following pseudo-C++:
template <typename T> using type = has_type<T::U> ? int : float;
or
template <typename T> using type = if_has_type<T::U, int, float>::type;
I considered using something like the method depicted at https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector (section "Detecting member types"), but I don't know how to implement a helper struct whose [sole] member type depends on the existence of another member type.
By using std::conditional
from <type_traits>
. It's as simple as:
using type = typename std::conditional<bool, int, float>::type;
or
using type = std::conditional_t<bool, int, float>;
where you replace bool
with some condition, evaluable at compile-time to a boolean value. In this case the condition is the check for an existing member.
If the condition is true
type becomes an alias to int
, otherwise to float
.
FULL EXAMPLE (Check if difference_type
is a member type.)
namespace detail {
template<class Ptr>
using ptrait_diff = typename Ptr::difference_type;
template<class Ptr, bool = is_detected<ptrait_diff, Ptr>::value>
struct ptrait_diff_t {
using type = ptrdiff_t;
};
template<class Ptr>
struct ptrait_diff_t<Ptr, true> {
using type = typename Ptr::difference_type;
};
} // namespace detail
and then:
template<class Ptr>
struct pointer_traits
{
using difference_type = typename detail::ptrait_diff_t<Ptr>::type;
};
Implementation of is_detected
can be found HERE.
This is the problem std::conditional is designed to solve.
#include <type_traits>
template<bool condition>
using type = std::conditional_t<condition, int, float>;
static_assert(std::is_same<type<true>, int>::value, "type<true> should be int");
static_assert(std::is_same<type<false>, float>::value, "type<false> should be float");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With