Namespaces
Variants

std::optional<T>:: emplace

From cppreference.net
Utilities library
template < class ... Args >
T & emplace ( Args && ... args ) ;
(1) (C++17以降)
(C++20以降 constexpr)
template < class U, class ... Args >
T & emplace ( std:: initializer_list < U > ilist, Args && ... args ) ;
(2) (C++17以降)
(C++20以降 constexpr)

含まれる値をその場で構築します。呼び出し前に * this が既に値を保持している場合、保持されている値はそのデストラクタを呼び出すことで破棄されます。

1) 含まれる値を direct-initializing (ただしdirect-list-initializingではない)によって初期化します。パラメータとして 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";
    // optは値を含んでいるため、その値も破棄されます
    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++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 正しい動作
P2231R1 C++20 emplace constexpr ではなかったが、必要な操作はC++20で constexpr 化可能 constexpr

関連項目

内容を代入
(public member function)