std::vector<T,Allocator>::emplace
template< class... Args > iterator emplace( const_iterator pos, Args&&... args ); |
(с C++11) (до C++20) |
|
template< class... Args > constexpr iterator emplace( const_iterator pos, Args&&... args ); |
(с C++20) |
Вставляет новый элемент в контейнер непосредственно перед pos.
Элемент создается с помощью std::allocator_traits::construct, что обычно использует размещающее new для создания элемента на месте в позиции, предоставленной контейнером. Однако, если необходимая позиция уже занята существующим элементом, вставляемый элемент сначала создается в другом месте, а затем перемещающее присваивание выполняется в требуемой позиции.
Аргументы args... передаются конструктору в качестве std::forward<Args>(args).... args... может напрямую или косвенно ссылаться на значение в контейнере.
Если после операции новое size() больше старого capacity(), происходит перераспределение, в этом случае все итераторы (включая итератор end()) и все ссылки на элементы становятся недействительными. В противном случае действительными остаются только итераторы и ссылки перед точкой вставки.
Параметры
| pos | - | итератор перед которым будет создан новый элемент |
| args | - | аргументы для передачи конструктору элемента |
| Требования к типу | ||
-T (the container's element type) должен соответствовать требованиям MoveAssignable, MoveInsertable и EmplaceConstructible. |
||
Возвращаемое значение
Итератор, указывающий на помещенный элемент.
Сложность
Линейная по расстоянию между pos и концом контейнера.
Исключения
Если возникает исключение, отличное от исключения, вызванного конструктором копирования, конструктором перемещения, оператором присваивания или оператором перемещения присваивания типа значения, или если возникает исключение при использовании emplace для вставки единственного элемента в конец, и тип значения является либо CopyInsertable, либо конструктор перемещения без исключений, то никаких эффектов нет (сильная гарантия исключения).
В противном случае эффекты не определены.
Пример
#include <iostream>
#include <string>
#include <vector>
struct A
{
std::string s;
A(std::string str) : s(std::move(str)) { std::cout << " constructed\n"; }
A(const A& o) : s(o.s) { std::cout << " copy constructed\n"; }
A(A&& o) : s(std::move(o.s)) { std::cout << " move constructed\n"; }
A& operator=(const A& other)
{
s = other.s;
std::cout << " copy assigned\n";
return *this;
}
A& operator=(A&& other)
{
s = std::move(other.s);
std::cout << " move assigned\n";
return *this;
}
};
int main()
{
std::vector<A> container;
// reserve enough place so vector does not have to resize
container.reserve(10);
std::cout << "construct 2 times A:\n";
A two { "two" };
A three { "three" };
std::cout << "emplace:\n";
container.emplace(container.end(), "one");
std::cout << "emplace with A&:\n";
container.emplace(container.end(), two);
std::cout << "emplace with A&&:\n";
container.emplace(container.end(), std::move(three));
std::cout << "content:\n";
for (const auto& obj : container)
std::cout << ' ' << obj.s;
std::cout << '\n';
}Вывод:
construct 2 times A: constructed constructed emplace: constructed emplace with A&: copy constructed emplace with A&&: move constructed content: one two three
Отчеты об ошибках
Следующие отчеты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применено к | Поведение, как опубликовано | Корректное поведение |
|---|---|---|---|
| LWG 2164 | C++11 | не было ясно, могут ли аргументы ссылаться на контейнер | уточнено |
См. также
| вставляет элементы (публичный член-функция) |
|
|
(C++11) |
создает элемент на месте в конце (публичный член-функция) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/container/vector/emplace