C ++ std :: unique_ptr:为什么lambdas没有任何大小费用? [英] C++ std::unique_ptr : Why isn't there any size fees with lambdas?
问题描述
我正在读有效的现代C ++。在与 std :: unique_ptr
相关的项目中声明,如果自定义删除程序是无状态对象,则不会发生大小费用,但如果它是一个函数指针或 std :: function
发生大小。
I am reading "Effective Modern C++". In the item related to std::unique_ptr
it's stated that if the custom deleter is a stateless object, then no size fees occur, but if it's a function pointer or std::function
size fee occurs. Could you explain why?
假设我们有以下代码:
auto deleter_ = [](int *p) { doSth(p); delete p; };
std::unique_ptr<int, decltype(deleter_)> up(new int, deleter_);
根据我的理解, unique_ptr
类型为 decltype(deleter _)
的对象,并将 deleter _
分配给该内部对象。但显然这不是发生了什么。
To my understanding, the unique_ptr
should have an object of type decltype(deleter_)
and assign deleter_
to that internal object. But obviously that's not what's happening. Could you explain the mechanism behind this using smallest possible code example?
推荐答案
A unique_ptr
必须始终存储其删除程序。现在,如果删除器是没有状态的类类型,则 unique_ptr
可以使用空基本优化,以便删除程序不使用任何额外的空间。
A unique_ptr
must always store its deleter. Now, if the deleter is a class type with no state, then the unique_ptr
can make use of empty base optimization so that the deleter does not use any additional space.
这是如何完成不同的实现。例如, libc ++ 和MSVC都将托管指针和删除器存储在压缩对,如果其中一个所涉及的类型是一个空类。
How exactly this is done differs between implementations. For instance, both libc++ and MSVC store the managed pointer and the deleter in a compressed pair, which automatically gets you empty base optimization if one of the types involved is an empty class.
从上面的libc ++链接
From the libc++ link above
template <class _Tp, class _Dp = default_delete<_Tp> >
class _LIBCPP_TYPE_VIS_ONLY unique_ptr
{
public:
typedef _Tp element_type;
typedef _Dp deleter_type;
typedef typename __pointer_type<_Tp, deleter_type>::type pointer;
private:
__compressed_pair<pointer, deleter_type> __ptr_;
libstdc ++ 在 std :: tuple
中存储两个,一些Google搜索建议他们的 tuple
实现使用空基本优化,但我找不到任何明确说明的文档。
libstdc++ stores the two in an std::tuple
and some Google searching suggests their tuple
implementation employs empty base optimization but I can't find any documentation stating so explicitly.
无论如何,此示例演示了libc ++和libstdc ++都使用EBO来减小 unique_ptr
与一个空的删除者。
In any case, this example demonstrates that both libc++ and libstdc++ use EBO to reduce the size of a unique_ptr
with an empty deleter.
这篇关于C ++ std :: unique_ptr:为什么lambdas没有任何大小费用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!