std::variant<Types...>::operator=

来自cppreference.com
< cpp‎ | utility‎ | variant
 
 
 
 
constexpr variant& operator=( const variant& rhs );
(1) (C++17 起)
constexpr variant& operator=( variant&& rhs ) noexcept(/* see below */);
(2) (C++17 起)
template< class T >
variant& operator=( T&& t ) noexcept(/* see below */);
(3) (C++17 起)

给既存的 variant 对象赋新值。

1) 复制赋值:
  • *thisrhs 均因异常无值,则不做任何事。
  • 否则,若 rhs 无值,但 *this 非无值,则销毁 *this 中所含值并使之无值。
  • 否则,若 rhs 保有同 *this 的可选项,则赋值 rhs 中含有的值给 *this 。若抛出异常,则 *this 不变为无值:值取决于该可选项的复制赋值的异常安全保证。
  • 否则,若 rhs 的可选项为 nothrow 可复制构造或 nothrow 可移动构造(分别由 std::is_nothrow_copy_constructiblestd::is_nothrow_move_constructible 确定),则等价于 this->emplace<rhs.index()>(get<rhs.index()>(rhs))
  • 否则,等价于 this->operator=(variant(rhs)) 。注意 *this 可能如 (2) 中描述一般变成因异常无值 (valueless_by_exception) 。
定义此重载为被删除,除非 std::is_copy_constructible_v<T_i>std::is_copy_assignable_v<T_i>Types... 中所有 T_i 均为 true 。若 std::is_trivially_copy_constructible_v<T_i>std::is_trivially_copy_assignable_v<T_i>std::is_trivially_destructible_v<T_i>Types... 中所有 T_i 均为 true 则此重载为平凡。
2) 移动赋值:
  • *thisrhs 均因异常无值,则不做任何事
  • 否则,若 rhs 无值,但 *this 非无值,则销毁 *this 中所含值并使之无值
  • 否则,若 rhs 保有与 *this 相同的可选项,则赋值 std::get<j>(std::move(rhs)) 给中所含值 *this ,其中 jindex() 。若抛出异常,则 *this 不变为无值:值依赖于可该选项的移动赋值的异常安全保证。
  • 否则(若 rhs*this 保有不同可选项),等价于 this->emplace<rhs.index()>(get<rhs.index()>(std::move(rhs))) 。若 T_i 的移动构造函数抛出异常,则 *this 变为因异常无值 (valueless_by_exception) 。
此重载仅若 std::is_move_constructible_v<T_i>std::is_move_assignable_v<T_i>Types... 中所有 T_itrue 才参与重载决议。若 std::is_trivially_move_constructible_v<T_i>std::is_trivially_move_assignable_v<T_i>std::is_trivially_destructible_v<T_i>Types... 中所有 T_i 均为 true 则此重载为平凡。
3) 转换赋值:
  • 确定若有对每个来自 Types...T_i 的虚构重载函数 F(T_i) 同时在作用域中,则重载决议是否为表达式 F(std::forward<T>(t)) 选择可选项类型 T_j ,除了:
  • 仅若声明 T_i x[] = { std::forward<T>(t) }; 对某个虚设变量 x 合法才考虑 F(T_i)
  • T_i 是(可有 cv 限定的) bool ,则仅若 std:remove_cvref_t<T> 亦为 bool 才考虑 F(T_i)
此重载仅若 std::decay_t<T> (C++20 前)std::remove_cvref_t<T> (C++20 起) 不是与 variant 相同的类型,且 std::is_assignable_v<T_j&, T> 为 true 而 std::is_constructible_v<T_j, T> 为 true 而且表达式 F(std::forward<T>(t)) (其中 F 为上述虚构函数集)为良式才参与重载决议。
std::variant<string> v1;
v1 = "abc"; // OK
std::variant<std::string, std::string> v2;
v2 = "abc"; // 错误
std::variant <std::string, bool> v3;
v3 = "abc"; // OK :选择 string ; bool 不是候选
std::variant<float, long, double> v4; // 保有 float
v4 = 0; // OK :保有 long ; float 与 double 不是候选

参数

rhs - 另一 variant
t - 可转换成 variant 的可选项之一的值

返回值

*this

异常

1) 可能抛出任何可选项的赋值及复制/移动初始化所抛的异常
2)
noexcept 规定:  
3)
noexcept 规定:  

示例

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR 应用于 出版时的行为 正确行为
LWG 3024 C++17 若任何成员类型不可复制则复制赋值运算符不参与重载决议 改为定义为被删除
P0602R4 C++17 即使底层操作平凡,复制/移动运算符亦可能不平凡 要求传播平凡性
P0608R3 C++17 转换赋值盲目地组成重载集,导致不想要的转换 不考虑窄化和布尔转换

参阅

原位构造 variant 中的值
(公开成员函数)