【问题标题】:Variadic CRTP Base Class with Additional Template Parameters带有附加模板参数的可变 CRTP 基类
【发布时间】:2021-03-30 04:09:57
【问题描述】:

我有一个特征类,即将在可变参数 CRTP 中使用,以扩展 SmartPointer 类的功能。

这个问题是https://stackoverflow.com/a/65373058/5677080的后续问题

一个示例特征类:

template<typename DERIVED, typename DELETER>
class Owning { 
public:
    using deleter_type = DELETER;
    
    /* ... */
};

下面是我的 SmartPointer 的实现,它由这些 trait 类通过可变参数 CRTP 进行扩展:

template<typename T, template<typename> class POINTER_TRAITS>
class SmartPointer;

template<typename T, template<typename> class POINTER_TRAITS>
struct element_type<SmartPointer<T, POINTER_TRAITS>>
{
    using type = T;
};


template<template<typename, typename...> class... TRAITS>
struct make_traits
{
    template<typename DERIVED>
    struct Traits : public TRAITS<DERIVED>... {};
};
template<typename T, template<typename> class POINTER_TRAITS>
class SmartPointer : public POINTER_TRAITS<SmartPointer<T, POINTER_TRAITS>> {
public:
    using pointer = T*;
    using element_type = T;

    /* ... */
};

最后是定义特定智能指针类型的类型别名(这里是unique_ptr

template<typename T, typename DELETER = DefaultDeleter<T>>
using unique_ptr = SmartPointer<T, make_traits<MoveablePointer, Owning>::template Traits>;

问题是如何将DELETER模板参数交给unique_ptr类型别名中的Owning类...

我猜是这样的(非工作代码,只是为了展示意图):

template<typename T, typename DELETER = DefaultDeleter<T>>
using unique_ptr = SmartPointer<T, make_traits<MoveablePointer, Owning<DELETER>>::template Traits>;
                                                                ^^^^^^^^^^^^^^^

【问题讨论】:

    标签: c++ variadic-templates c++20 crtp


    【解决方案1】:

    大概是这样的:

    template <typename DELETER>
    struct MakeOwningWithDeleter {
      template <typename T>
      using type = Owning<T, DELETER>
    };
    

    现在您可以将MakeOwningWithDeleter&lt;DELETER&gt;::type 传递给make_traits。您已经在 make_traits 上使用过同样的技巧。

    【讨论】:

      【解决方案2】:
      template<template<class...>class Z, class...Ts>
      struct Partial{
         template<class...Us>
         using Apply=Z<Ts...,Us...>;
      };
      

      然后

       template<typename T, typename DELETER = DefaultDeleter<T>>
       using unique_ptr = SmartPointer<T, make_traits<MoveablePointer, Partial<Owning,DELETER>::template Apply>::template Traits>;
      

      这确实需要更改:

      template<typename DELETER, typename DERIVED>
      class Owning { 
      

      【讨论】:

      • 或更改Partial 中的顺序以修复最后一个参数而不是第一个(逻辑)参数。
      • @jarod surs,但我宁愿元函数简单而著名。过去论点的部分应用有点模糊。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      • 2011-08-06
      • 1970-01-01
      • 2021-08-09
      • 1970-01-01
      • 1970-01-01
      • 2014-09-08
      相关资源
      最近更新 更多