gpt4 book ai didi

c++ - GCC 和 VC++ 之间 std::vector::emplace_back 的区别

转载 作者:可可西里 更新时间:2023-11-01 18:00:04 26 4
gpt4 key购买 nike

<分区>

我听说 Modern C++ 的建议之一是使用 emplace_back 而不是 push_back 来追加到容器中( emplace_back 接受容器中存储类型的任何构造函数的任何版本参数。

根据标准草案N3797 23.3.6.5 (1),说:

Remarks: Causes reallocation if the new size is greater than the old capacity. If no reallocation happens, all the iterators and references before the insertion point remain valid. If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of T or by any InputIterator operation there are no effects. If an exception is thrown by the move constructor of a non-CopyInsertable T, the effects are unspecified.

这指定了当不需要重新分配时会发生什么,但是当容器需要增长时将问题留待解决。

在这段代码中:

#include <iostream>
#include <vector>

int main() {
std::vector<unsigned char> buff {1, 2, 3, 4};
buff.emplace_back(buff[0]);
buff.push_back(buff[1]);
for (const auto& c : buff) {
std::cout << std::hex << static_cast<long>(c) << ", ";
}
std::cout << std::endl;
return 0;
}

使用 VC++(Visual Studio 2013 Update 4)GCC 4.9.1 (MinGW) 在 Windows 8.1 中调试编译。

当用 VC++ 编译时,输出是:

1, 2, 3, 4, dd, 2

当使用 GCC 编译时,输出是:

1, 2, 3, 4, 1, 2

检查emplace_back在VC++中的实现,不同之处在于第一行代码,检查容器是否需要增长(如果需要则增长),如果容器需要增长增长时,对 emplace_back 方法中接收到的第一个元素 (buff[0]) 的引用无效,并且当该值的实际设置在新创建的元素中时容器发生值无效。

push_back 的情况下,因为要附加的元素的创建是在参数绑定(bind)中进行的(在容器可能增长之前)。

我的问题是:这种行为,当容器需要增长时,因为调用 emplace_back 并且参数是对同一容器的引用是实现定义的,未指定的,或者在实现之一中存在问题编译器(假设在 VC++ 中,因为 GCC 行为更接近预期)?

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