问题
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