std::make_unique_for_overwrite() 相对于 std::make_unique() 有什么作用?

问题描述 投票:0回答:3

看来在 C++20 中,我们为智能指针提供了一些额外的实用函数,包括:

template<class T> unique_ptr<T> make_unique_for_overwrite();
template<class T> unique_ptr<T> make_unique_for_overwrite(size_t n);

std::make_shared
std::shared_ptr
相同。为什么现有的功能没有:

template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args); // with empty Args
template<class T> unique_ptr<T> make_unique(size_t n);

够了吗?现有的不是使用对象的默认构造函数吗?

注意:在这些函数的早期提案中,名称为

make_unique_default_init()

c++ smart-pointers c++20
3个回答
21
投票

这些新功能不同:

  • 原始
    make_XYZ
    始终初始化指向的值(“显式初始化”,请参阅标准中的§class.expl.init)。
  • make_XYZ_for_overwrite
    :执行指向值的“默认初始化”(参见§dcl.init,标准中的第7段);在典型的机器上,这意味着对于非类、非数组类型“实际上没有初始化”。 (是的,这个术语有点令人困惑;请阅读链接中的段落。)
  • 这是普通指针的一个功能,智能指针实用程序函数不提供该功能:使用常规指针,您可以直接分配而无需实际初始化指向的值:

new int

对于唯一/共享指针,您只能通过包装现有指针来实现此目的,如下所示:

std::unique_ptr<int[]>(new int[n])

现在我们有一个包装函数。

注意:请参阅相关的 ISO C++ WG21

提案 以及 这个 SO 答案


15
投票
allocate_shared

make_shared
make_unique
都通过执行与
new T(args...)
等效的操作来初始化底层对象。在零参数的情况下,这会减少到
new T()
- 也就是说,它执行
值初始化。在许多情况下,值初始化(包括像 int
char
这样的标量类型、它们的数组以及它们的聚合)执行
零初始化 - 也就是说,这是为了将 a 归零而进行的实际工作。一堆数据。
也许您想要这个并且这对您的申请很重要,也许您不需要。从 

P1020R1

开始,论文介绍了最初名为 make_unique_default_init

make_shared_default_init
allocate_shared_default_init
的函数(在 C++20 的全国投票评论过程中,这些函数从
meow_default_init
重命名为
meow_for_overwrite
):

内置类型的数组(例如
unsigned char

double
)在分配后立即由用户整体初始化的情况并不罕见。在这些情况下,由
allocate_shared
make_shared
make_unique
执行的值初始化是多余的并且会损害性能,因此需要一种选择默认初始化的方法。

也就是说,如果您编写如下代码:

auto buffer = std::make_unique<char[]>(100); read_data_into(buffer.get());

make_unique

执行的值初始化会将这 100 个字节清零,这是完全没有必要的,因为无论如何你都会立即覆盖它。

新的 

meow_for_overwrite

函数改为执行

默认初始化,因为所使用的内存无论如何都会立即被覆盖(因此得名) - 这就是说相当于执行 new T (没有任何括号或大括号)。在我之前提到的那些情况下(例如 
int
char
、它们的数组以及它们的聚合),默认初始化不执行初始化,这节省了时间。

对于具有用户提供的默认构造函数的类类型,值初始化和默认初始化之间没有区别:两者都只是调用默认构造函数。但对于许多其他类型,可能存在很大差异。


0
投票
make_unique

使用

calloc()
make_unique_for_overwrite
使用
malloc()
它存在的意义在于 malloc 通常比 calloc 更快。

© www.soinside.com 2019 - 2024. All rights reserved.