2

我在cppreference.com中读到 new(自 C++17 起)std::vector::emplace_back具有对插入元素的引用的返回值。

返回值

  • (无)(C++17 前)
  • 对插入元素的引用。(C++17 起)

我在想,在向向量插入元素时,为什么我们需要引用它?这怎么可能有用,或者这个新回报的用例是什么?

这是我写的一个示例代码,用于查看该功能。

#include <vector>

int main()
{
    std::vector<int> myVec;
    for(int i = 0; i < 3; ++i)
    {
        int& newElement = myVec.emplace_back(i);
        ^^^^^^^ => why standard should expose the element after inserting.
    }
}
4

3 回答 3

8

更改由P0084 进行。作者给出的动机是

emplace_front我经常发现自己想使用or创建容器的元素emplace_back,然后访问该元素,以进一步修改它或简单地使用它。所以我发现自己在写这样的代码:

my_container.emplace_back(...);
my_container.back().do_something(...);

也许:

my_container.emplace_back(...);
do_something_else(my_container.back());

一个非常常见的特定情况是,我需要在获得将其置于最终状态所需的所有信息之前构造一个对象,例如当我从文件中读取它时:

my_container.emplace_back(); // Default construct.
my_container.back().read(file_stream); // Read the object.

这种情况经常发生,以至于我倾向于编写调用某个版本emplace并返回的小模板,这对我来说似乎相当不必要。我相信emplace_frontandemplace_back函数应该返回对新创建元素的非常量引用,以符合当前标准库在实用时返回有用信息的趋势。在最初的emplace提案中,他们没有这样做是一个疏忽(就我而言)。

于 2018-11-10T15:06:58.023 回答
4
std::cout << vec.emplace_back(7);

这只是方便,因此您可以在表达式中做不止一件事。

vec.emplace_back().reg();

它所做的任何事情都可以被复制

(void(vec.emplace_back()), vec.back()).reg();

在 C++17 之前的版本中(这里的无效是面向未来的妄想症)

创建对象并立即使用它是一种常见的模式;返回值使它稍微容易一些。

于 2018-11-10T15:03:59.427 回答
0

崩溃警报!使用(返回的)引用要非常小心,尤其是在添加另一个元素之后。然后向量倾向于重新分配内存,并且首先返回的引用不再有效,从而导致内存异常!例子:

std::vector <int> intVector;

int& a0 = intVector.emplace_back(0);
int& a1 = intVector.emplace_back(1);  // a0& invalid
int& a2 = intVector.emplace_back(2);  // a0& and a1& invalid

如果你最后看一下向量本身,一切似乎都很好 {0,1,2}。如果您查看 a0 和 a1,那只是垃圾。原因:de 向量已被重新分配,导致引用指向无处。顺便说一句:出于同样的原因,使用 back() 函数也会给您带来麻烦。

于 2021-11-19T22:09:06.447 回答