如果需要存储删除器,unique_ptr如何没有开销? [英] How can unique_ptr have no overhead if it needs to store the deleter?

查看:87
本文介绍了如果需要存储删除器,unique_ptr如何没有开销?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先看看C ++ Primer关于 unique_ptr shared_ptr 的内容:

16.1.6美元。效率和灵活性


我们可以确定 shared_ptr 不成立将该删除器作为直接成员,因为该删除器的类型直到运行时才知道。


因为该删除器的类型是 unique_ptr ,删除成员的类型在编译时是已知的。 删除程序可以直接存储在每个 unique_ptr 对象中。


因此,似乎 shared_ptr 没有删除程序的直接成员,但是 unique_ptr 却没有。但是,顶部投票通过的另一个问题的答案说:


如果您提供删除程序作为模板参数(如 unique_ptr )是该类型的一部分,您无需在此类型的对象中存储任何其他内容。如果将deleter作为构造函数的参数传递(例如 shared_ptr ),则您需要将其存储在对象中。这是额外灵活性的代价,因为您可以对相同类型的对象使用不同的删除器。


两个引用的段落完全冲突,这会导致冲突。让我感到困惑。而且,许多人说 unique_ptr 的开销为零,因为它不需要将删除程序存储为成员。但是,众所周知, unique_ptr 具有 unique_ptr< obj,del>的构造函数。 p(new obj,fcn),这意味着我们可以将删除器传递给它,因此 unique_ptr 似乎已将删除器存储为成员。

解决方案

std :: unique_ptr< T> 是很有可能是零开销(使用任何理智的标准库实现)。对于任意 D std :: unique_ptr< T,D> 通常不具有零开销。 / p>

原因很简单:在删除器为空(因此为无状态)类型(例如<$ c $)的情况下,可以使用空基优化来消除删除器的存储c> std :: default_delete 实例化。)


First take a look at what C++ Primer said about unique_ptr and shared_ptr:
$16.1.6. Efficiency and Flexibility

We can be certain that shared_ptr does not hold the deleter as a direct member, because the type of the deleter isn’t known until run time.

Because the type of the deleter is part of the type of a unique_ptr, the type of the deleter member is known at compile time. The deleter can be stored directly in each unique_ptr object.

So it seems like that the shared_ptr does not have a direct member of deleter, but unique_ptr does. However, the top-voted answer of another question says:

If you provide the deleter as template argument (as in unique_ptr) it is part of the type and you don't need to store anything additional in the objects of this type. If deleter is passed as constructor's argument (as in shared_ptr) you need to store it in the object. This is the cost of additional flexibility, since you can use different deleters for the objects of the same type.

The two quoted paragraph are totally conflicting, which makes me confused. What's more, many people says unique_ptr is zero overhead because it doesn't need to store the deleter as member. However, as we know, unique_ptr has a constructor of unique_ptr<obj,del> p(new obj,fcn), which means that we can pass a deleter to it, so unique_ptr seems to have stored deleter as a member. What a mess!

解决方案

std::unique_ptr<T> is quite likely to be zero-overhead (with any sane standard-library implementation). std::unique_ptr<T, D>, for an arbitrary D, is not in general zero-overhead.

The reason is simple: Empty-Base Optimisation can be used to eliminate storage of the deleter in case it's an empty (and thus stateless) type (such as std::default_delete instantiations).

这篇关于如果需要存储删除器,unique_ptr如何没有开销?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆