使用可变 CRTP 的智能指针工具包
Smart pointer toolkit using variadic CRTP
我即将设计和实现一种智能指针工具包 - 一组 classes 来定义各种类型的智能指针,如 unique_ptr、intrusive_ptr、shared_ptr、observing_ptr、tagged_ptr 等。顺便提一下,我在没有可用的 C++ 库的独立环境中工作。我的干预是避免代码重复,使其遵循优雅的设计原则。让我在那里描述一下我的想法。
设计注意事项:
我想使用可变 CRTP 方法来混合所需的指针功能,特征。对于每个特征集,应该有一个特征class,比如:
/* Functions to support move semantics like move constructor, move assignment operator */
template<typename DERIVED>
class MoveablePointer { ... };
/* Functions to manage pointee lifetime - using the deleter class */
/* EDIT: template<typename DERIVED, typename DELETER = DefaultDeleter<typename DERIVED::element_type>> */
template<typename DERIVED, typename DELETER> /* <-------- Default removed here as EDIT */
class Owning {
public:
using deleter_type = DELETER;
/* ... */
};
/* Functions to use least significant bits effectively unused due to alignment to hold additional payload information */
template<typename DERIVED, typename TAGS, size_t ALIGNMENT>
class Tagged { ... };
然后使用可变 CRTP 模式将特征混合到一个智能指针中class:
template<template<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;
/* ... */
};
template<typename T, typename DELETER = DefaultDeleter<T>>
using unique_ptr = SmartPointer<T, make_traits<MoveablePointer, Owning>>;
template<typename T>
using observer_ptr = SmartPointer<T, make_traits<Observing, NonOwning, Copyable, Moveable>>;
/* ... and to continue defining type aliases to cover various smart pointer variations... */
基本上,一旦特定特征具有相同的模板参数集(只是 template<typename DERIVED>
),这个想法似乎就起作用了。但正如上面的示例,情况并非如此,例如 Tagged
特征或 Owning
特征分别需要更多模板参数,例如 ALIGNMENT
或 DELETER
。
所以我的问题是 - 如何更改 make_traits<> 和 SmartPointer<> class 模板的实现以支持可变特征的模板参数?
非常感谢愿意帮助我的人!马丁
编辑:代码随着讨论在答案下方进行调整...
您可能会使用可变参数模板:
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;
/* ... */
};
template<typename T, typename DELETER = DefaultDeleter<T>>
using unique_ptr = SmartPointer<T, make_traits<MoveablePointer, Owning>::template Traits>;
template<typename T>
using observer_ptr = SmartPointer<T, make_traits<Observing, NonOwning, Copyable, MoveablePointer>::template Traits>;
我即将设计和实现一种智能指针工具包 - 一组 classes 来定义各种类型的智能指针,如 unique_ptr、intrusive_ptr、shared_ptr、observing_ptr、tagged_ptr 等。顺便提一下,我在没有可用的 C++ 库的独立环境中工作。我的干预是避免代码重复,使其遵循优雅的设计原则。让我在那里描述一下我的想法。
设计注意事项: 我想使用可变 CRTP 方法来混合所需的指针功能,特征。对于每个特征集,应该有一个特征class,比如:
/* Functions to support move semantics like move constructor, move assignment operator */
template<typename DERIVED>
class MoveablePointer { ... };
/* Functions to manage pointee lifetime - using the deleter class */
/* EDIT: template<typename DERIVED, typename DELETER = DefaultDeleter<typename DERIVED::element_type>> */
template<typename DERIVED, typename DELETER> /* <-------- Default removed here as EDIT */
class Owning {
public:
using deleter_type = DELETER;
/* ... */
};
/* Functions to use least significant bits effectively unused due to alignment to hold additional payload information */
template<typename DERIVED, typename TAGS, size_t ALIGNMENT>
class Tagged { ... };
然后使用可变 CRTP 模式将特征混合到一个智能指针中class:
template<template<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;
/* ... */
};
template<typename T, typename DELETER = DefaultDeleter<T>>
using unique_ptr = SmartPointer<T, make_traits<MoveablePointer, Owning>>;
template<typename T>
using observer_ptr = SmartPointer<T, make_traits<Observing, NonOwning, Copyable, Moveable>>;
/* ... and to continue defining type aliases to cover various smart pointer variations... */
基本上,一旦特定特征具有相同的模板参数集(只是 template<typename DERIVED>
),这个想法似乎就起作用了。但正如上面的示例,情况并非如此,例如 Tagged
特征或 Owning
特征分别需要更多模板参数,例如 ALIGNMENT
或 DELETER
。
所以我的问题是 - 如何更改 make_traits<> 和 SmartPointer<> class 模板的实现以支持可变特征的模板参数?
非常感谢愿意帮助我的人!马丁
编辑:代码随着讨论在答案下方进行调整...
您可能会使用可变参数模板:
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;
/* ... */
};
template<typename T, typename DELETER = DefaultDeleter<T>>
using unique_ptr = SmartPointer<T, make_traits<MoveablePointer, Owning>::template Traits>;
template<typename T>
using observer_ptr = SmartPointer<T, make_traits<Observing, NonOwning, Copyable, MoveablePointer>::template Traits>;