嵌套std::vector的移动语义和时间复杂度<std::vector<std::string>>右值赋值

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

如果有具有以下签名的函数:

std::vector<std::vector<std::string>> some_func();

并将其分配给相同类型的变量:

std::vector<std::vector<std::string>> var = some_func();

这个赋值操作的时间复杂度是多少?明显的假设是,这将是一个移动赋值操作,并且比常规的逐元素复制到

var
更快。

但是我不确定移动赋值操作是否只会将外部向量的位置/大小信息移动到

var
并让内部向量的指针和大小信息相同,或者内部向量也会被移动逐个元素?

如果是这样的话,右值引用会更快吗? :

std::vector<std::vector<std::string>>&& var = some_func();

c++ move-semantics return-value-optimization move-assignment-operator
1个回答
0
投票
std::vector<std::vector<std::string>> var = some_func();

这个赋值操作的时间复杂度是多少。

没有赋值操作。 这不是赋值,而是复制初始化。 请参阅初始化和赋值有什么区别?

由于

some_func
按值返回
std::vector
,因此从
some_func
返回的对象与 var
 是同一个对象
。 另请参阅保证复制省略如何工作?

在 C++17 之前,这最多就是对移动构造函数的一次调用,其复杂性恒定(请参阅 (8))。

如果是这样的话,右值引用会更快吗? :

std::vector<std::vector<std::string>>&& var = some_func();

不,这和

var
一样贵。 这具体化了
some_func()
返回的临时对象,但就像第一个示例一样,只有一个对象。 这段代码自 C++17 以来更加糟糕,因为它更复杂,但没有任何收获。

最后但并非最不重要的一点是,您很可能不需要

std::vector
向量。 这将是一个二维数据结构,其中每行可以有不同的长度,而这很少是可取的。 更简单的形式是单个
std::vector
,包裹在
std::mdspan
std::views::chunk
等中。根据需要。

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