C++ 在调用emplace_back时修改std::deque是否合法?
我正在使用C++ 在调用emplace_back时修改std::deque是否合法?,c++,c++11,language-lawyer,deque,libc++,C++,C++11,Language Lawyer,Deque,Libc++,我正在使用emplace\u back将项目添加到std::deque。在构建过程中,新项目可能会将其他项目添加到正在构建的std::deque中。这导致了非常有趣的行为。考虑这个片段: #include <iostream> #include <deque> #include <string> struct foo { std::string m_marker; foo(std::deque<foo>& into, c
emplace\u back
将项目添加到std::deque
。在构建过程中,新项目可能会将其他项目添加到正在构建的std::deque
中。这导致了非常有趣的行为。考虑这个片段:
#include <iostream>
#include <deque>
#include <string>
struct foo
{
std::string m_marker;
foo(std::deque<foo>& into, const std::string& marker, bool createInner = true)
: m_marker(marker)
{
if (createInner)
{
std::cout << "Marker is " << m_marker << std::endl;
into.emplace_back(into, "my other marker", false);
std::cout << "Marker is now " << m_marker << std::endl;
}
}
};
int main()
{
std::deque<foo> foos;
foos.emplace_back(foos, "my initial marker");
std::cout << "There are " << foos.size() << " items in the deque:" << std::endl;
for (foo& f : foos)
{
std::cout << f.m_marker << std::endl;
}
}
然而,对于clang++(tags/Apple/clang-421.11.66)和libc++(不确定是什么版本),我得到的是:
Marker is my initial marker
Marker is now my other marker
There are 2 items in the deque:
my other marker
正如您所看到的,第一个对象的
m_marker
字段被第二个对象覆盖,显示在deque中的第二个对象现在为空。很明显,某个地方有一个bug,它必须是在调用emplace\u back
期间修改deque
是未定义的行为,或者libc++没有完成它的工作。这是哪一个?正如Howard Hinnant回答的那样,标准没有说明任何关于这个案例的内容,但需要说明的是,它将导致未定义的行为:
在每种情况下,出于例外安全考虑
容器在构建foo之前不会被“修改”
完成这样,如果foo构造函数抛出
国家没有改变。例如,vector.size()直到
foo构造函数已完成。所以当第二个
在第一个项目完成之前就开始施工了,现在还没有完工
附加到零长度向量
这不是一个可以在执行《公约》时解决的问题
集装箱。标准需要说“不要那样做。”
因此,不要期望它与任何实现一起工作。为什么要这样做?!你可能会感兴趣的一个相关问题:我认为这是一种未定义的行为。本标准仅对函数运行前后提供保证。仅供参考:谢谢@HowardHinnant!我基本上复制了你下面的答案。如果你喜欢互联网积分,请随意发布同样的内容,我会接受你的。
Marker is my initial marker
Marker is now my other marker
There are 2 items in the deque:
my other marker