跳到主要内容

std::variant<Types...>::emplace

声明

// 1)
template <class T, class... Args>
constexpr T& emplace(Args&&... args);
// 2)
template <class T, class U, class... Args>
constexpr T& emplace( std::initializer_list<U> il, Args&&... args );
// 3)
template <std::size_t I, class... Args>
constexpr std::variant_alternative_t<I, variant>& emplace( Args&&... args );
// 4)
template <std::size_t I, class U, class... Args>
constexpr std::variant_alternative_t<I, variant>&
emplace( std::initializer_list<U> il, Args&&... args );

在现有的 variant 对象中就地创建一个新值


等同于 emplace<I>(std::forward<Args>(args)...),其中 ITTypes... 中的基于零的索引。

  • 此重载仅在 std::is_constructible_v<T, Args...> 为真,且 TTypes... 中恰好出现一次时参与重载决议。

等同于 emplace<I>(il, std::forward<Args>(args)...),其中 ITTypes... 中的基于零的索引。

  • 此重载仅在 std::is_constructible_v<T, std::initializer_list<U>&, Args...> 为真,且 TTypes... 中恰好出现一次时参与重载决议。

首先,销毁当前包含的值(如果有)。然后直接初始化包含的值,如同使用参数 std::forward<Args>(args)... 构造 T_I 类型的值。如果抛出异常,*this 可能会变为 valueless_by_exception

  • 此重载仅在 std::is_constructible_v<T_I, Args...> 为真时参与重载决议。
  • 如果 I 不小于 sizeof...(Types),则为编译时错误。

首先,销毁当前包含的值(如果有)。然后直接初始化包含的值,如同使用参数 il, std::forward<Args>(args)... 构造 T_I 类型的值。如果抛出异常,*this 可能会变为 valueless_by_exception

  • 此重载仅在 std::is_constructible_v<T_I, std::initializer_list<U>&, Args...> 为真时参与重载决议。
  • 如果 I 不小于 sizeof...(Types),则为编译时错误。

参数

args - 构造新值时使用的构造函数参数 il - 构造新值时使用的 initializer_list 参数

返回值

新包含值的引用。

异常

1-4) 在初始化包含值期间抛出的任何异常。

示例

#include <iostream>
#include <string>
#include <variant>

int main()
{
std::variant<std::string> v1;
v1.emplace<0>("abc"); // OK
std::cout << std::get<0>(v1) << '\n';
v1.emplace<std::string>("def"); // OK
std::cout << std::get<0>(v1) << '\n';

std::variant<std::string, std::string> v2;
v2.emplace<1>("ghi"); // OK
std::cout << std::get<1>(v2) << '\n';
// v2.emplace<std::string>("abc"); -> Error
}
结果
abc
def
ghi

缺陷报告 以下行为更改缺陷报告被追溯应用于先前发布的 C++ 标准。

缺陷报告应用于发布时的行为正确行为
P2231R1C++20emplace 在 C++20 中不是 constexpr,而所需的运算可以是 constexpr变为 constexpr

std::variant<Types...>::emplace

声明

// 1)
template <class T, class... Args>
constexpr T& emplace(Args&&... args);
// 2)
template <class T, class U, class... Args>
constexpr T& emplace( std::initializer_list<U> il, Args&&... args );
// 3)
template <std::size_t I, class... Args>
constexpr std::variant_alternative_t<I, variant>& emplace( Args&&... args );
// 4)
template <std::size_t I, class U, class... Args>
constexpr std::variant_alternative_t<I, variant>&
emplace( std::initializer_list<U> il, Args&&... args );

在现有的 variant 对象中就地创建一个新值


等同于 emplace<I>(std::forward<Args>(args)...),其中 ITTypes... 中的基于零的索引。

  • 此重载仅在 std::is_constructible_v<T, Args...> 为真,且 TTypes... 中恰好出现一次时参与重载决议。

等同于 emplace<I>(il, std::forward<Args>(args)...),其中 ITTypes... 中的基于零的索引。

  • 此重载仅在 std::is_constructible_v<T, std::initializer_list<U>&, Args...> 为真,且 TTypes... 中恰好出现一次时参与重载决议。

首先,销毁当前包含的值(如果有)。然后直接初始化包含的值,如同使用参数 std::forward<Args>(args)... 构造 T_I 类型的值。如果抛出异常,*this 可能会变为 valueless_by_exception

  • 此重载仅在 std::is_constructible_v<T_I, Args...> 为真时参与重载决议。
  • 如果 I 不小于 sizeof...(Types),则为编译时错误。

首先,销毁当前包含的值(如果有)。然后直接初始化包含的值,如同使用参数 il, std::forward<Args>(args)... 构造 T_I 类型的值。如果抛出异常,*this 可能会变为 valueless_by_exception

  • 此重载仅在 std::is_constructible_v<T_I, std::initializer_list<U>&, Args...> 为真时参与重载决议。
  • 如果 I 不小于 sizeof...(Types),则为编译时错误。

参数

args - 构造新值时使用的构造函数参数 il - 构造新值时使用的 initializer_list 参数

返回值

新包含值的引用。

异常

1-4) 在初始化包含值期间抛出的任何异常。

示例

#include <iostream>
#include <string>
#include <variant>

int main()
{
std::variant<std::string> v1;
v1.emplace<0>("abc"); // OK
std::cout << std::get<0>(v1) << '\n';
v1.emplace<std::string>("def"); // OK
std::cout << std::get<0>(v1) << '\n';

std::variant<std::string, std::string> v2;
v2.emplace<1>("ghi"); // OK
std::cout << std::get<1>(v2) << '\n';
// v2.emplace<std::string>("abc"); -> Error
}
结果
abc
def
ghi

缺陷报告 以下行为更改缺陷报告被追溯应用于先前发布的 C++ 标准。

缺陷报告应用于发布时的行为正确行为
P2231R1C++20emplace 在 C++20 中不是 constexpr,而所需的运算可以是 constexpr变为 constexpr