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