std::optional<T>::emplace
Материал из cppreference.com
<tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
| (1) | ||
template< class... Args > T& emplace( Args&&... args ); |
(начиная с C++17) (до C++20) |
|
template< class... Args > constexpr T& emplace( Args&&... args ); |
(начиная с C++20) | |
| (2) | ||
template< class U, class... Args > T& emplace( std::initializer_list<U> ilist, Args&&... args ); |
(начиная с C++17) (до C++20) |
|
template< class U, class... Args > constexpr T& emplace( std::initializer_list<U> ilist, Args&&... args ); |
(начиная с C++20) | |
Создаёт содержащееся значение на месте. Если *this уже содержит значение до вызова, содержащееся значение уничтожается вызовом его деструктора.
1) Инициализирует содержащееся значение путём прямой инициализации (но не прямой инициализации списком) с
std::forward<Args>(args)... в качестве параметров.2) Инициализирует содержащееся значение, вызывая его конструктор с параметрами
ilist, std::forward<Args>(args).... Эта перегрузка участвует в разрешении перегрузки, только если std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value равно true.Параметры
| args... | — | аргументы для передачи конструктору |
| ilist | — | список инициализаторов для передачи в конструктор |
| Требования к типам | ||
-T должен быть создан из Args... для перегрузки (1)
| ||
-T должен быть создан из std::initializer_list и Args... для перегрузки (2)
| ||
Возвращаемое значение
Ссылка на новое содержащееся значение.
Исключения
Любое исключение, созданное выбранным конструктором объекта T. Если возникает исключение, *this не содержит значения после этого вызова (ранее содержащееся значение, если оно было, будет уничтожено).
Пример
Запустить этот код
#include <optional>
#include <iostream>
struct A {
std::string s;
A(std::string str) : s(std::move(str)), id{n++} { note("+ создан"); }
~A() { note("~ уничтожен"); }
A(const A& o) : s(o.s), id{n++} { note("+ создан копированием"); }
A(A&& o) : s(std::move(o.s)), id{n++} { note("+ создан перемещением"); }
A& operator=(const A& other) {
s = other.s;
note("= присвоен копированием");
return *this;
}
A& operator=(A&& other) {
s = std::move(other.s);
note("= присвоен перемещением");
return *this;
}
inline static int n{};
int id{};
void note(auto s) { std::cout << " " << s << " #" << id << '\n'; }
};
int main()
{
std::optional<A> opt;
std::cout << "Присваивание:\n";
opt = A("Lorem ipsum dolor sit amet, consectetur adipiscing elit nec.");
std::cout << "Emplace:\n";
// Поскольку opt содержит значение, оно также уничтожит это значение.
opt.emplace("Lorem ipsum dolor sit amet, consectetur efficitur.");
std::cout << "Конец примера\n";
}
Вывод:
Присваивание:
+ создан #0
+ создан перемещением #1
~ уничтожен #0
Emplace:
~ уничтожен #1
+ создан #2
Конец примера
~ уничтожен #2
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| WG не указан | C++20 | emplace не была constexpr, в то время как необходимые операциимогут быть constexpr в C++20 |
сделана constexpr |
Смотрите также
| присваивает содержимое (public функция-элемент) |