std::vector<T,Allocator>::emplace
template< class... Args > iterator emplace( const_iterator pos, Args&&... args ); |
(начиная с C++11) (constexpr начиная с C++20) |
Вставляет новый элемент в контейнер непосредственно перед pos.
Элемент конструируется с помощью std::allocator_traits::construct, который обычно использует размещающий new для конструирования элемента на месте по адресу, предоставленному контейнером. Однако если требуемое место занято существующим элементом, вставляемый элемент сначала конструируется в другом месте, а затем перемещается в требуемое место с помощью операции присваивания.
Аргументы args... передаются конструктору как std::forward<Args>(args).... args... может прямо или косвенно ссылаться на значение в контейнере.
Если после выполнения операции новый size() больше старого capacity(), происходит перераспределение памяти, при котором все итераторы (включая итератор end()) и все ссылки на элементы становятся недействительными. В противном случае остаются действительными только итераторы и ссылки, находящиеся до точки вставки.
Параметры
| pos | - | итератор, перед которым будет сконструирован новый элемент |
| args | - | аргументы, передаваемые конструктору элемента |
| Требования к типам | ||
-T должен соответствовать требованиям MoveAssignable, MoveInsertable и EmplaceConstructible. |
||
Возвращаемое значение
Итератор, указывающий на вставленный элемент.
Сложность
Линейная относительно расстояния между pos и end().
Исключения
Если исключение выбрасывается не конструктором копирования, конструктором перемещения, оператором присваивания или оператором перемещающего присваивания T, либо если исключение выбрасывается при использовании emplace для вставки одного элемента в конец и T является 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++.
| Отчёт об ошибке | Применён к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| LWG 2164 | C++11 | не было ясно, могут ли аргументы ссылаться на контейнер | прояснено |
См. также
| вставляет элементы (открытая функция-член) |
|
|
(C++11) | конструирует элемент на месте в конце (открытая функция-член) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/container/vector/emplace