请考虑以下std::vector<T>
的insert
和emplace
成员函数:
template <class... Args> iterator emplace(const_iterator position, Args&&... args);
iterator insert(const_iterator position, const T& x);
iterator insert(const_iterator position, T&& x);
iterator insert(const_iterator position, size_type n, const T& x);
如果其中一个使用向量本身的元素作为参数调用,会发生什么?通常,它们中的每一个都会使从position
开始的所有元素的引用无效,这可能包括参数,或者如果发生重新分配,则会使对全部元素的引用,其中肯定包括它,但这是否意味着这样的调用无效,或者插入(似乎)先发生?
查看一些常见实现会得到奇怪的结果:
libstdc++在
const T&
重载的insert
中移动任何元素之前复制参数。 它包含以下注释:三个操作的顺序由C++0x case指定,其中move操作可能会修改现有向量中属于新元素的对象。 这只适用于通过const lvalue ref获取元素的调用者(请参阅23.1/13)。
但是,C++11 §23.1只是容器库的简要摘要,即使我们假设这是指§23.2.1(在C++03中曾经是§23.1),§23.2.1/13也仅提供了allocator-aware容器的定义,似乎与此无关。 我已经查看了第23章,但是我没有在任何地方找到任何相关内容。
libc++在
emplace
中移动任何元素之前创建一个临时对象,而在insert
中,它首先移动元素,但是将参数引用转换为指针,并调整它以确保它指向原始元素-但是,它仅在const T&
重载中执行所有这些操作。Visual C++在所有情况下在移动任何元素之前复制/创建一个临时对象。
我错过了标准定义这种行为的地方吗? 为什么我查看的三个C ++库彼此不同意? 为什么libstdc ++注释说这只是insert(const_iterator,const T&)
的问题? 如果标准不要求这起作用,那么为什么库要费力使其起作用? (肯定会造成一些可以避免的复制和/或移动。)最后,如果我正在实现应该类似于std :: vector
的容器,我应该让这个工作吗?
std::array
。 - Chortos-2