gpt4 book ai didi

c++ - 为什么 C++ std::map::operator[] 不使用 inplace new?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:34:32 29 4
gpt4 key购买 nike

如果您将 C++ std::map(和其他容器)与值类型一起使用,您会注意到插入映射会调用元素类型的析构函数。这是因为 C++ 规范要求 operator [] 的实现等同于:

(*((std::map<>::insert(std::make_pair(x, T()))).first)).second

它调用您类型的默认构造函数来构建该对。然后将该临时值复制到 map 中,然后销毁。对此的确认可以在 this stackoverflow post 中找到和 here on codeguru .

我觉得奇怪的是,这可以在不需要临时变量的情况下实现,并且仍然是等价的。 C++ 有一个特性叫做 "inplace new" . std::map 和其他容器可以为对象分配空白空间,然后在分配的空间上显式调用元素的默认构造函数。

我的问题:为什么我见过的 std::map 实现都没有使用 inplace new 来优化这个操作?在我看来,它会大大提高这种低级操作的性能。但是很多人都研究过 STL 代码库,所以我认为这样做一定是有原因的。

最佳答案

通常,您指定一个更高级别的操作,如 []在较低级别的方面是个好主意。

在 C++11 之前,用 [] 这样做如果不使用 insert 会很困难.

在 C++11 中,添加了 std::map<?>::emplace和类似的东西 std::pair使我们能够避免该问题。如果您重新定义它以便使用这种就地构造,额外的(希望被省略的)对象创建将会消失。

我想不出不这样做的理由。我鼓励您提出标准化建议。

演示无拷贝插入 std::map ,我们可以做到以下几点:

#include <map>
#include <iostream>

struct no_copy_type {
no_copy_type(no_copy_type const&)=delete;
no_copy_type(double) {}
~no_copy_type() { std::cout << "destroyed\n"; }
};
int main() {
std::map< int, no_copy_type > m;
m.emplace(
std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple(3.14)
);
std::cout << "destroy happens next:\n";
}

live example -- 如您所见,没有生成临时文件。

所以如果我们替换

(*((std::map<>::insert(std::make_pair(x, T()))).first)).second

(*
(
(
std::map<>::emplace(
std::piecewise_construct,
std::forward_as_tuple(std::forward<X>(x)),
std::forward_as_tuple()
)
).first
).second

不会创建临时文件(添加空格以便我可以跟踪 () s)。

关于c++ - 为什么 C++ std::map::operator[] 不使用 inplace new?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26021118/

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