gpt4 book ai didi

c++ - 如果使用 lambda,std::unique_ptr 如何没有大小开销

转载 作者:行者123 更新时间:2023-11-30 03:13:28 28 4
gpt4 key购买 nike

跟进这个问题,
How can std::unique_ptr have no size overhead?

我做了以下代码,结果有点出乎意料:

#include <memory>

#include <cstdio>

void f(void *p){
free(p);
}

int main(){
auto x1 = [](void *p){ free(p); };
auto x2 = [](void *p){ f(p); };

printf("%zu\n", sizeof(std::unique_ptr<int> )); // 8, expected
printf("%zu\n", sizeof(std::unique_ptr<int, decltype(&f)> )); // 16, expected
printf("%zu\n", sizeof(std::unique_ptr<int, decltype(x1)> )); // 8, unexpected
printf("%zu\n", sizeof(std::unique_ptr<int, decltype(x2)> )); // 8, unexpected
}

lambda 的最后两种类型的大小为 8,即使它们做的事情与 f() 相同。

这是怎么做到的?

最佳答案

无捕获的 lambda 不需要有任何子对象;它只是一种具有 operator() 的类型重载。因此,它可以是(但不一定是)空类型。 unqiue_ptr允许(但不是必需)优化它“包含”删除器类型的方式,这样,如果删除器类型是一个空类类型,那么它可以使用各种技术来确保该类型不会占用存储在unique_ptr实例本身。

有几种方法可以做到这一点。 unique_ptr可以从类型继承,依靠 EBO 优化掉基类。使用 C++20,它可以使它成为一个成员子对象,依赖于 [[no_unique_address]]属性以提供空成员优化。在任何一种情况下,唯一的实际存储 unique_ptr<T>需要的是指向 T 的指针.

相比之下,函数指针就是函数指针。它是一种必须具有存储空间的基本类型,因为它可以指向具有该签名的任何函数。类型本质上包含要调用的成员函数,作为类型本身的一部分;函数指针没有。该类型的实例实际上不需要存储来找到它的 operator() .

关于c++ - 如果使用 lambda,std::unique_ptr 如何没有大小开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58666958/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com