Spec-Zone.ru › C++

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 не было ясно, могут ли аргументы ссылаться на контейнер уточнено

См. также

insert
вставляет элементы
(публичный член-функция)
emplace_back
(C++11)
создает элемент на месте в конце
(публичный член-функция)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/container/vector/emplace

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API