Net*_*peC 8 c++ gcc stdvector visual-c++ c++11
我听说Modern C++的一个建议是使用emplace_back而不是push_back在容器中追加(emplace_back接受容器中任何类型存储的构造函数的任何版本的参数).
根据标准草案N3797 23.3.6.5(1),说:
备注:如果新大小大于旧容量,则会导致重新分配.如果没有重新分配,插入点之前的所有迭代器和引用仍然有效.如果除了复制构造函数之外抛出异常,移动构造函数,赋值运算符或T的移动赋值运算符,或者通过任何InputIterator操作都没有效果.如果非CopyInsertable T的移动构造函数抛出异常,则不指定效果.
这指定了在不需要重新分配时会发生什么,但在容器需要增长时保持打开问题.
在这段代码中:
#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;
}
Run Code Online (Sandbox Code Playgroud)
编译VC++(Visual Studio的2013更新4)和GCC 4.9.1(MinGW的)在调试在Windows 8.1.
使用VC++编译时,输出为:
1, 2, 3, 4, dd, 2
Run Code Online (Sandbox Code Playgroud)
使用GCC编译时,输出为:
1, 2, 3, 4, 1, 2
Run Code Online (Sandbox Code Playgroud)
检查emplace_backVC++中的实现差异在于第一行代码,检查容器是否需要增长(如果需要则增长),在容器需要增长的情况下,引用第一个元素(buff [ 0])在emplace_back方法中接收到无效,并且当容器的新创建元素中的值的实际设置发生时,该值无效.
在工作的情况下,push_back因为要在参数绑定中创建要追加的元素(在容器可能增长之前).
我的问题是:这种行为,当容器需要增长时因为调用emplace_back而参数是对同一容器的引用是实现定义,未指定或者在编译器的实现中存在问题(假设在VC++中为海湾合作委员会的行为更接近预期)?
小智 0
当您使用 &operator[] 时,它返回一个引用。然后,您使用 emplace_back 导致重新分配,从而使所有过去的引用无效。这两条规则都有明确的定义。应该发生的正确事情是例外。实际上,如果您在调试器下运行调试版本,我实际上希望 VC++ 版本会抛出异常。
Push_back 有相同的两个规则,这意味着它也会做同样的事情。我几乎可以肯定,交换两行 emplace_back/push_back 将导致相同的行为。
| 归档时间: |
|
| 查看次数: |
613 次 |
| 最近记录: |