c++ - 如何安全地重载 std::unique_ptr 的自定义删除器?

标签 c++ memory-management c++17 smart-pointers unique-ptr

我试图在使用 std::unique_ptr 及其自定义删除器时减少代码重复。

我有一些容器FooBar,它们是使用一个自定义分配器分配的,因此无法通过delete<释放.

所以当前的代码是:

struct UniqueFooDeleter
{
   void operator()(Foo* foo) 
   {
      internal_free(foo);
   }
};
using unique_foo_ptr = std::unique_ptr<Foo, UniqueFooDeleter>;

struct UniqueBarDeleter 
{
   void operator()(Bar* bar) 
   {
      internal_free(bar);
   }
};
using unique_bar_ptr = std::unique_ptr<Bar, UniqueBarDeleter>;

我把它改为:

struct UniqueInternalDeleter
{
   void operator()(Bar* bar)
   {
      internal_free(bar);
   }

   void operator()(Foo* foo)
   {
      internal_free(foo);
   }
};
using unique_bar_ptr = std::unique_ptr<Bar, UniqueInternalDeleter>;
using unique_foo_ptr = std::unique_ptr<Foo, UniqueInternalDeleter>;

如何做得更好,以便通过 internal_free 分配的任意数量的容器都可以用作 std::unique_ptr

最佳答案

您可以将UniqueInternalDeleter设为模板化仿函数和 static_assert ,如果 T 不是 Foobar

#include <type_traits> // std::is_same_v

template<typename T>
struct UniqueInternalDeleter /* final */
{
   static_assert(std::is_same_v<T, Foo> || std::is_same_v<T, Bar>,
      " T must be either Foo or Bar");

   void operator()(T* barOrfoo)
   {
      internal_free(barOrfoo);
   }

private:
   void internal_free(T* barOrfoo)
   {
      if constexpr(std::is_same_v<T, Foo>)
         // code for `Foo*`
      else
         // code for `Bar*`

   }
};

这使得您的别名对于 BarFoo 更加具体:

using unique_bar_ptr = std::unique_ptr<Bar, UniqueInternalDeleter<Bar>>;
using unique_foo_ptr = std::unique_ptr<Foo, UniqueInternalDeleter<Foo>>;

关于c++ - 如何安全地重载 std::unique_ptr 的自定义删除器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63206760/

相关文章:

c++ - TreeView_SetExtendedStyle 不应用某些样式,我做错了什么?

c++ - 如何使用 call 和 alloca 指令在 llvm 字节码中定位类名?

c++ - 如何为类提供几个可变参数模板模板参数

memory - 在 VB6 应用程序中识别内存占用的工具

c++ - 使用 C++ new[] 为二维数组分配内存

c++ - 在释放内存之前总是重新分配内存是否安全 - C++

c++ - 为什么不允许 std::variant 与其替代类型之一进行相等比较?

c++ - 派生类中的模板有问题

c++ - 了解此代码中的 “Callable”对象/事物

visual-studio-2017 - VS2017 : E0135 namespace "std" has no member "filesystem"