"Conditional" 别名模板
"Conditional" alias templates
在像非专用模板结构 pointer_traits
(即 template <class Ptr> struct pointer_traits
)这样的类型中,存在一个定义为 Ptr::rebind<U>
的成员别名模板 rebind
,如果它存在,或者其他一些类型。虽然我已经看到一些关于 检查 某个成员是否存在的答案,但是如何实现像 pointer_traits::rebind
这样的 "conditional" 别名模板?也就是说,就好像通过以下伪 C++:
template <typename T> using type = has_type<T::U> ? int : float;
或
template <typename T> using type = if_has_type<T::U, int, float>::type;
我考虑过使用类似于 https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector(第 "Detecting member types" 节)中描述的方法,但我不知道如何实现其 [唯一] 成员类型取决于存在的辅助结构另一种成员类型。
通过使用 <type_traits>
中的 std::conditional
。就这么简单:
using type = typename std::conditional<bool, int, float>::type;
或
using type = std::conditional_t<bool, int, float>;
将 bool
替换为某些条件,可在 compile-time 处评估为布尔值。在这种情况下,条件是检查现有成员。
如果条件为 true
,则类型成为 int
的别名,否则为 float
。
完整示例(检查 difference_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
然后:
template<class Ptr>
struct pointer_traits
{
using difference_type = typename detail::ptrait_diff_t<Ptr>::type;
};
可以找到 is_detected
的实现 HERE。
这就是std::conditional旨在解决的问题。
#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");
在像非专用模板结构 pointer_traits
(即 template <class Ptr> struct pointer_traits
)这样的类型中,存在一个定义为 Ptr::rebind<U>
的成员别名模板 rebind
,如果它存在,或者其他一些类型。虽然我已经看到一些关于 检查 某个成员是否存在的答案,但是如何实现像 pointer_traits::rebind
这样的 "conditional" 别名模板?也就是说,就好像通过以下伪 C++:
template <typename T> using type = has_type<T::U> ? int : float;
或
template <typename T> using type = if_has_type<T::U, int, float>::type;
我考虑过使用类似于 https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector(第 "Detecting member types" 节)中描述的方法,但我不知道如何实现其 [唯一] 成员类型取决于存在的辅助结构另一种成员类型。
通过使用 <type_traits>
中的 std::conditional
。就这么简单:
using type = typename std::conditional<bool, int, float>::type;
或
using type = std::conditional_t<bool, int, float>;
将 bool
替换为某些条件,可在 compile-time 处评估为布尔值。在这种情况下,条件是检查现有成员。
如果条件为 true
,则类型成为 int
的别名,否则为 float
。
完整示例(检查 difference_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
然后:
template<class Ptr>
struct pointer_traits
{
using difference_type = typename detail::ptrait_diff_t<Ptr>::type;
};
可以找到 is_detected
的实现 HERE。
这就是std::conditional旨在解决的问题。
#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");