GCC和VC之间std::vector::emplace_back的差异++; P>我听说现代C++的一个建议是使用 EngutsRead 代替在容器中追加的 PuxSuff-( EnStudioRead >接受容器中类型存储的任何构造函数的任何版本参数)。

GCC和VC之间std::vector::emplace_back的差异++; P>我听说现代C++的一个建议是使用 EngutsRead 代替在容器中追加的 PuxSuff-( EnStudioRead >接受容器中类型存储的任何构造函数的任何版本参数)。,c++,visual-c++,c++11,gcc,stdvector,C++,Visual C++,C++11,Gcc,Stdvector,根据标准草案23.3.6.5(1),规定: 备注:如果新容量大于旧容量,则会导致重新分配。如果没有重新分配,则插入点之前的所有迭代器和引用都保持有效。如果异常不是由T的复制构造函数、移动构造函数、赋值运算符或移动赋值运算符或任何InputIterator操作引发的,则不会产生任何影响。如果非CopyInsertable T的move构造函数引发异常,则未指定效果 这将指定当不需要重新分配时会发生什么,但当容器需要增长时,问题仍然存在 在这段代码中: #include <iostream&g

根据标准草案23.3.6.5(1),规定:

备注:如果新容量大于旧容量,则会导致重新分配。如果没有重新分配,则插入点之前的所有迭代器和引用都保持有效。如果异常不是由T的复制构造函数、移动构造函数、赋值运算符或移动赋值运算符或任何InputIterator操作引发的,则不会产生任何影响。如果非CopyInsertable T的move构造函数引发异常,则未指定效果

这将指定当不需要重新分配时会发生什么,但当容器需要增长时,问题仍然存在

在这段代码中:

#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;
}
使用GCC编译时,输出为:

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

push_back
的情况下,由于要追加的元素是在参数绑定中创建的(在容器可能增长之前)

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

当使用&operator[]时,它返回了一个引用。然后使用emplace_back,这会导致重新分配,从而使所有过去的引用无效。这两条规则都有很好的定义。应该发生的正确事情是例外。实际上,如果在调试器下运行调试版本,我希望VC++版本会引发异常


push_back有两个相同的规则,这意味着它也将执行相同的操作。我几乎可以肯定,交换两行emplace_back/push_back将导致相同的行为。

是这样吗?我想知道为什么以及它可能会起作用。以下是我论文的更好视图:相关/重复:从相关问题重新发布:他反对我上面链接的LWG 760的拟议解决方案的地方。