"Conditional"别名模板

"Conditional" alias templates

本文关键字:别名 Conditional      更新时间:2023-10-16

在像非专用模板结构pointer_traits这样的类型中(即 template <class Ptr> struct pointer_traits ),存在一个成员别名模板rebind,该模板被定义为Ptr::rebind<U>,如果存在,则为其他类型。虽然我已经看到了一些关于检查某个成员是否存在的答案,但如何实现像 pointer_traits::rebind 这样的"条件"别名模板?也就是说,好像通过以下伪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 中描述的方法("检测成员类型"部分),但我不知道如何实现其 [唯一] 成员类型依赖于另一个成员类型的存在的帮助程序结构。

通过使用 <type_traits> 中的std::conditional .它就像:

using type = typename std::conditional<bool, int, float>::type;

using type = std::conditional_t<bool, int, float>;

bool替换为某些条件,在编译时可评估为布尔值。在这种情况下,条件是对现有成员的检查。

如果条件为 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的实施可以在这里找到。

这就是 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");