Variadic CRTP Base Class with Additional Template Parameters

余生长醉 提交于 2021-01-07 02:19:19

问题


I have a trait classes which are about to be used in variadic CRTP to extend the features of SmartPointer class.

This question is created as the followup of https://stackoverflow.com/a/65373058/5677080

An example trait class:

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

Here comes the implemnetation of my SmartPointer which is being extended by variadic CRTP by those trait classes:

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;

    /* ... */
};

Finally there comes the type alias to define particular smart pointer type (here unique_ptr)

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

The problem is how to hand over the DELETER template parameter to the Owning class in unique_ptr type alias...

I guess something like (non-working code, just to demonstrate the intension):

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

回答1:


Something along these lines, perhaps:

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

Now you can pass MakeOwningWithDeleter<DELETER>::type to make_traits. Same trick you already use for make_traits.




回答2:


template<template<class...>class Z, class...Ts>
struct Partial{
   template<class...Us>
   using Apply=Z<Ts...,Us...>;
};

then

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

This does require this change:

template<typename DELETER, typename DERIVED>
class Owning { 


来源:https://stackoverflow.com/questions/65375096/variadic-crtp-base-class-with-additional-template-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!