【问题标题】:"Conditional" alias templates“条件”别名模板
【发布时间】:2017-01-18 16:09:05
【问题描述】:

在像非特化模板结构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(“检测成员类型”一节)中描述的方法,但我不知道如何实现一个辅助结构,其 [sole] 成员类型取决于另一个成员类型的存在.

【问题讨论】:

    标签: c++ templates template-meta-programming sfinae


    【解决方案1】:

    通过使用来自&lt;type_traits&gt;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 的实现可以在HERE 找到。

    【讨论】:

    • 我认为 op 对条件的外观比 std::conditional 更感兴趣
    • std::conditional的实现看起来很容易理解,但是is_detected是如何工作的呢?此外,虽然我是 C++17 新特性的粉丝,但 pointer_traits 是在 C++11 中实现的。如果不使用 [实验性] C++17 功能,如何实现这一点?
    • @AliciaRose 如果不使用 [experimental] C++17 功能,如何实现呢? 丑陋而痛苦。您可以在线查找您的标准库的源代码。
    • "std::is_detected 存在于 C++17" 不。 “using difference_type = conditional_t&lt;is_detected&lt;detail::ptrait_diff, Ptr&gt;::value, typename Ptr::difference_type, ptrdiff_t&gt;;”双重不。在您知道它存在之前,您不能尝试访问typename Ptr::difference_type。如果您尝试使用检测习语,这是detected_or 的教科书用例,而不是is_detected
    • @T.C.正确的。感谢您的关注。我没有试运行任何这些。出于某种原因,我相信 std::is_detected 已将其纳入标准。你每天都会感到失望......
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-20
      • 2021-12-18
      相关资源
      最近更新 更多