gpt4 book ai didi

c++11 - 在 C++11 中编写持有 STL 容器的类的构造函数的最佳方法

转载 作者:行者123 更新时间:2023-12-04 00:16:50 25 4
gpt4 key购买 nike

class Foo {
std::vector<SomeType> data_;
};

Foo只能通过复制 std::vector<SomeType> 来构建(技术上我的意思是复制或 move )目的。为 Foo 编写构造函数的最佳方法是什么? ?

我的第一感觉是
Foo(std::vector<SomeType> data) noexcept : data_(std::move(data)) {};

使用它,实例的构造需要 0 或 1 次向量复制,具体取决于 {data} 的参数是否可 move 。

最佳答案

你的第一感觉很好。严格来说不是最优的。但它是如此接近最优,以至于你有理由说你不在乎。

解释:

Foo(std::vector<SomeType> data) noexcept : data_(std::move(data)) {};

当客户端传入一个左值 std::vector<SomeType>将制作 1 个副本以绑定(bind)到 data争论。然后将采取 1 步将参数“复制”到 data_ .

当客户端传入一个 xvalue std::vector<SomeType>将进行 1 次 move 以绑定(bind)到 data争论。然后将采取另一措施将参数“复制”到 data_。 .

当客户端传入prvalue时 std::vector<SomeType>在绑定(bind)到 data 时,该 move 将被忽略。争论。然后将采取 1 步将参数“复制”到 data_ .

概括:
client argument    number of copies     number of moves
lvalue 1 1
xvalue 0 2
prvalue 0 1

如果你这样做了:
Foo(const std::vector<SomeType>&  data)          : data_(data) {};
Foo( std::vector<SomeType>&& data) noexcept : data_(std::move(data)) {};

然后你有一个非常高的性能:

当客户端传入一个左值 std::vector<SomeType>将制作 1 个副本以将参数复制到 data_ .

当客户端传入一个 xvalue std::vector<SomeType>将采取 1 步将参数“复制”到 data_ .

当客户端传入prvalue时 std::vector<SomeType>将采取 1 步将参数“复制”到 data_ .

概括:
client argument    number of copies     number of moves
lvalue 1 0
xvalue 0 1
prvalue 0 1

结论:
std::vector move 结构非常便宜,尤其是在副本方面。

当客户端传入左值时,第一个解决方案将花费您额外的 Action 。与必须分配内存的副本成本相比,这很可能处于噪声级别。

当客户端传入 xvalue 时,第一个解决方案将花费您额外的 Action 。这可能是解决方案的一个弱点,因为它会使成本翻倍。性能测试是确保这是或不是问题的唯一可靠方法。

当客户端传递一个纯右值时,这两种解决方案是等效的。

随着构造函数中参数数量的增加,第二种方案的维护成本呈指数增长。也就是说,您需要每个参数的 const lvalue 和 rvalue 的每种组合。这在 1 个参数(两个构造函数)时非常易于管理,在 2 个参数(4 个构造函数)时不太容易管理,之后很快变得难以管理(8 个具有 3 个参数的构造函数)。因此,最佳性能并不是这里唯一的问题。

如果一个人有很多参数,并且担心左值和 xvalue 参数的额外 move 构造的成本,还有其他解决方案,但它们涉及相对丑陋的模板元编程技术,许多人认为这些技术太丑陋而无法使用(我不,但我试图保持公正)。

对于 std::vector ,额外 move 构造的成本通常足够小,您将无法在整体应用程序性能中对其进行衡量。

关于c++11 - 在 C++11 中编写持有 STL 容器的类的构造函数的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21963062/

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