来自以下文档的摘录emplace_back()
:
- 迭代器有效性
与此容器相关的所有迭代器都无效,但指针和引用仍然有效,引用它们在调用之前引用的相同元素。
- 数据竞赛
容器被修改。
调用不会访问包含的元素:同时访问或修改它们是安全的(尽管请参阅上面的迭代器有效性)。
以及来自以下文档的摘录operator[]()
:
- 数据竞赛
访问容器(const 和非 const 版本都不会修改容器)。
元素n可能被访问或修改。同时访问或修改其他元素是安全的。
那么,鉴于双端队列的某些实例至少有一个元素,通过容器访问它operator[]()
并同时调用emplace_back()
它确实是线程安全的吗?
我倾向于说是,但无法确定emplace_back()
's 文档中的“访问”是否包括使用operator[]()
as:
int access( std::deque< int > & q )
{
return q[ 0 ];
}
void emplace( std::deque< int > & q , int i )
{
q.emplace_back( i );
}
其中两个函数被同时调用,或者“访问”仅适用于已获取某些引用或指针的元素:
std::deque< int > q { 1 };
auto * ptr = & q[ 0 ]
std::thread t1 ( [ ptr ]{ * ref = 0; } );
std::thread t2 ( [ & q ]{ q.emplace_back( 2 ); } );
编辑:为了进一步参考,以下是 C++ 14 标准(实际上是2014 年 11 月的工作草案,N4296)关于deque
引用和迭代器有效性的插入说明:
- 23.3.3.4 双端队列修饰符
(...)
- 效果:双端队列中间的插入使所有迭代器和对双端队列元素的引用无效。在双端队列的任何一端插入都会使双端队列的所有迭代器无效,但不会影响对双端队列元素的引用的有效性。
(...)