繁体   English   中英

std :: unique_ptr的内存效率自定义删除器?

[英]Memory-efficient custom deleter for std::unique_ptr?

这可能有点特定于实现,但有些似乎是基本的。

我确定我必须在标准库中遗漏一些东西。

问题是这样的:

我想实现一个std::unique_ptr其删除器是free()

[因为该值是通过malloc()分配的]

当然,有很多选项可以做到这一点,但(至少在g ++ 4.8.4 for x86-64中)它们似乎有不同的内存使用含义。

例如:方法1:

std::unique_ptr<char, std::function<void(void*)>> ptr_a(malloc(10), free);

但是, sizeof(ptr_a) == 40个字节(对于void *为8,对于std :: function <>为32)

方法2:

std::unique_ptr<void, void (*)(void*)> ptr_b(malloc(10), free);

sizeof(ptr_b)好一点,因为sizeof(ptr_b) == 16个字节(8个表示void *,8表示裸函数指针])

方法3:

template <void (*T)(void*)>
class Caller {
 public:
  void operator()(void* arg) {
    return T(arg);
  }
};
std::unique_ptr<void, Caller<free>> ptr_c(malloc(10));`

此时, sizeof(ptr_c) == 8个字节(最小可能) - 但我必须引入一个非常纯粹的样板(并且如图所示,容易模板化)的类。

这看起来像是一个简单的模式 - 在STL中是否有一些元素可以执行Caller<>上面的操作?

当然,默认情况下,当在一个普通类型上调用delete时,g ++确实看起来像free() - 但这似乎远不是标准所保证的(如果没有别的,可以从默认的分配/释放函数重新定义new / delete,并且然后default_delete将调用替换删除)。

此外,在其他情况下,在纯C库中分配的某些对象的发布将通过简单的函数调用而不是删除器来实现。 在类中包含这样的分配/释放函数似乎有点乏味,以便让std :: unique_ptr正确有效地调用它们 - 这让我觉得我缺少了一些东西(现代C ++规范的其余部分)似乎非常深思熟虑)。

C ++ 11有一个integral_constant类型,适用于非整数类的东西。 在C ++ 14中,有一个constexpr转换为该值。

所以,在C ++ 14中,我们可以做到:

std::unique_ptr<void, std::integral_constant<decltype(free)*, free>> ptr_c(malloc(10));

这很尴尬。 (这依赖于()将在其左侧参数上考虑转换为函数指针的事实。

我们可以免费硬编码:

using default_free = std::integral_constant<decltype(free)*, free>;
std::unique_ptr<void, default_free> ptr_c(malloc(10));

在使用现场摆脱一些噪音。

在C ++ 17中,我们可以编写一个帮助器:

template<auto t>
using val = std::integral_constant< std::decay_t<decltype(t)>, t >;

给我们:

std::unique_ptr<void, val<free>> ptr_c(malloc(10));

在我看来这更干净。

实例

我们可以在C ++ 11中编写自己的版本:

template<class T, std::decay_t<T> t>
struct val {
  constexpr operator T() noexcept const { return t; }
};
using default_free = val<decltype(free), free>;
std::unique_ptr<void, default_free> ptr_c(malloc(10));

还有第四种选择使用无状态lambda:

auto free_lmbd = [](void *_ptr) { free (_ptr);};
std::unique_ptr<void, decltype (free_lmbd)> ptr {malloc(10), free_lmbd};

它也有8个字节(至少在我的电脑上),与你的第3个选项相同。

我建议阅读http://www.bfilipek.com/2016/04/custom-deleters-for-c-smart-pointers.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM