std::optional<T>::emplace
template< class... Args > T& emplace( Args&&... args ); | (1) |
(начиная с C++17) (constexpr начиная с C++20) |
template< class U, class... Args > T& emplace( std::initializer_list<U> ilist, Args&&... args ); | (2) |
(начиная с C++17) (constexpr начиная с 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 не содержит значения (ранее хранившееся значение, если оно было, уничтожено).
| Макрос проверки возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_lib_optional | 202106L |
(C++20) (DR20) | Полностью constexpr (1,2) |
Пример
#include <iostream>
#include <optional>
struct A
{
std::string s;
A(std::string str) : s(std::move(str)), id{n++} { note("+ constructed"); }
~A() { note("~ destructed"); }
A(const A& o) : s(o.s), id{n++} { note("+ copy constructed"); }
A(A&& o) : s(std::move(o.s)), id{n++} { note("+ move constructed"); }
A& operator=(const A& other)
{
s = other.s;
note("= copy assigned");
return *this;
}
A& operator=(A&& other)
{
s = std::move(other.s);
note("= move assigned");
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 << "Assign:\n";
opt = A("Lorem ipsum dolor sit amet, consectetur adipiscing elit nec.");
std::cout << "Emplace:\n";
// As opt contains a value it will also destroy that value
opt.emplace("Lorem ipsum dolor sit amet, consectetur efficitur.");
std::cout << "End example\n";
}
Вывод:
Assign: + constructed #0 + move constructed #1 ~ destructed #0 Emplace: ~ destructed #1 + constructed #2 End example ~ destructed #2
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| Отчёт об ошибке | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| P2231R1 | C++20 |
emplace не был constexpr, хотя требуемые операции могут быть constexpr в C++20 | сделан constexpr |
См. также
| присваивает содержимое (общедоступная функция-член) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/optional/emplace