Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

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

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

      Assigns a new value to an existingvariant object.

      1) Copy-assignment:
      • If both*this andrhs are valueless by exception, does nothing.
      • Otherwise, ifrhs is valueless, but*this is not, destroys the value contained in*this and makes it valueless.
      • Otherwise, ifrhs holds the same alternative as*this, assigns the value contained inrhs to the value contained in*this. If an exception is thrown,*this does not become valueless: the value depends on the exception safety guarantee of the alternative's copy assignment.
      • Otherwise, if the alternative held byrhs is either nothrow copy constructible ornot nothrow move constructible (as determined bystd::is_nothrow_copy_constructible andstd::is_nothrow_move_constructible, respectively), equivalent tothis->emplace<rhs.index()>(*std::get_if<rhs.index()>(std::addressof(rhs))).*this may becomevalueless_by_exception if an exception is thrown on the copy-construction insideemplace.
      • Otherwise, equivalent tothis->operator=(variant(rhs)).
      This overload is defined as deleted unlessstd::is_copy_constructible_v<T_i> andstd::is_copy_assignable_v<T_i> are bothtrue for allT_i inTypes.... This overload is trivial ifstd::is_trivially_copy_constructible_v<T_i>,std::is_trivially_copy_assignable_v<T_i> andstd::is_trivially_destructible_v<T_i> are alltrue for allT_i inTypes....
      2) Move-assignment:
      • If both*this andrhs are valueless by exception, does nothing.
      • Otherwise, ifrhs is valueless, but*this is not, destroys the value contained in*this and makes it valueless.
      • Otherwise, ifrhs holds the same alternative as*this, assignsstd::move(*std::get_if<j>(std::addressof(rhs))) to the value contained in*this, withj beingindex(). If an exception is thrown,*this does not become valueless: the value depends on the exception safety guarantee of the alternative's move assignment.
      • Otherwise (ifrhs and*this hold different alternatives), equivalent tothis->emplace<rhs.index()>(std::move(*std::get_if<rhs.index()>(std::addressof(rhs)))). If an exception is thrown byT_i's move constructor,*this becomesvalueless_by_exception.
      This overload participates in overload resolution only ifstd::is_move_constructible_v<T_i> andstd::is_move_assignable_v<T_i> are bothtrue for allT_i inTypes.... This overload is trivial ifstd::is_trivially_move_constructible_v<T_i>,std::is_trivially_move_assignable_v<T_i>, andstd::is_trivially_destructible_v<T_i> are alltrue for allT_i inTypes....
      3) Converting assignment.
      • Determines the alternative typeT_j that would be selected by overload resolution for the expressionF(std::forward<T>(t)) if there was an overload of imaginary functionF(T_i) for everyT_i fromTypes... in scope at the same time, except that:
      • An overloadF(T_i) is only considered if the declarationT_i x[]={std::forward<T>(t)}; is valid for some invented variablex;

      This overload participates in overload resolution only ifstd::decay_t<T>(until C++20)std::remove_cvref_t<T>(since C++20) is not the same type asvariant andstd::is_assignable_v<T_j&, T> istrue andstd::is_constructible_v<T_j, T> istrue and the expressionF(std::forward<T>(t)) (with F being the above-mentioned set of imaginary functions) is well formed.

      std::variant<std::string> v1;v1="abc";// OKstd::variant<std::string,std::string> v2;v2="abc";// Errorstd::variant<std::string,bool> v3;v3="abc";// OK, chooses string; bool is not a candidatestd::variant<float,long,double> v4;// holds floatv4=0;// OK, holds long; float and double are not candidates

      Contents

      [edit]Parameters

      rhs - anothervariant
      t - a value convertible to one of the variant's alternatives

      [edit]Return value

      *this

      [edit]Exceptions

      1) May throw any exception thrown by assignment and copy/move initialization of any alternative.
      2)
      noexcept specification:  
      noexcept(((std::is_nothrow_move_constructible_v<Types>&&
                 std::is_nothrow_move_assignable_v<Types>)&& ...))
      3)
      noexcept specification:  
      noexcept(std::is_nothrow_assignable_v<T_j&, T>&&
               std::is_nothrow_constructible_v<T_j, T>)

      [edit]Notes

      Feature-test macroValueStdFeature
      __cpp_lib_variant202106L(C++20)
      (DR)
      Fullyconstexprstd::variant(3)

      [edit]Example

      Run this code
      #include <iomanip>#include <iostream>#include <string>#include <type_traits>#include <variant> std::ostream& operator<<(std::ostream& os,std::variant<int,std::string>const& va){    os<<": { "; std::visit([&](auto&& arg){using T=std::decay_t<decltype(arg)>;ifconstexpr(std::is_same_v<T,int>)            os<< arg;elseifconstexpr(std::is_same_v<T,std::string>)            os<<std::quoted(arg);}, va); return os<<" };\n";} int main(){std::variant<int,std::string> a{2017}, b{"CppCon"};std::cout<<"a"<< a<<"b"<< b<<'\n'; std::cout<<"(1) operator=( const variant& rhs )\n";    a= b;std::cout<<"a"<< a<<"b"<< b<<'\n'; std::cout<<"(2) operator=( variant&& rhs )\n";    a= std::move(b);std::cout<<"a"<< a<<"b"<< b<<'\n'; std::cout<<"(3) operator=( T&& t ), where T is int\n";    a=2019;std::cout<<"a"<< a<<'\n'; std::cout<<"(3) operator=( T&& t ), where T is std::string\n";std::string s{"CppNow"};std::cout<<"s: "<<std::quoted(s)<<'\n';    a= std::move(s);std::cout<<"a"<< a<<"s: "<<std::quoted(s)<<'\n';}

      Possible output:

      a: { 2017 };b: { "CppCon" }; (1) operator=( const variant& rhs )a: { "CppCon" };b: { "CppCon" }; (2) operator=( variant&& rhs )a: { "CppCon" };b: { "" }; (3) operator=( T&& t ), where T is inta: { 2019 }; (3) operator=( T&& t ), where T is std::strings: "CppNow"a: { "CppNow" };s: ""

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      LWG 3024C++17copy assignment operator doesn't participate in overload resolution
      if any member type is not copyable
      defined as deleted instead
      LWG 3585C++17converting assignment was sometimes unexpectedly ill-formed
      because there was no available move assignment
      made well-formed
      P0602R4C++17copy/move assignment may not be trivial
      even if underlying operations are trivial
      required to propagate triviality
      P0608R3C++17converting assignment blindly assembles an overload set,
      leading to unintended conversions
      narrowing and boolean conversions
      not considered
      P2231R1C++20converting assignment(3) was notconstexpr
      while the required operations can beconstexpr in C++20
      madeconstexpr

      [edit]See also

      constructs a value in thevariant, in place
      (public member function)[edit]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/utility/variant/operator%3D&oldid=172844"

      [8]ページ先頭

      ©2009-2025 Movatter.jp