Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Union declaration

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
       

      A union is a special class type that can hold only one of its non-staticdata members at a time.

      Contents

      [edit]Syntax

      The class specifier for a union declaration is similar toclass or struct declaration:

      unionattrclass-head-name{member-specification}
      attr -(since C++11) optional sequence of any number ofattributes
      class-head-name - the name of the union that's being defined. Optionally prepended bynested-name-specifier (sequence of names and scope-resolution operators, ending with scope-resolution operator). The name may be omitted, in which case the union isunnamed
      member-specification - list of access specifiers, member object and member function declarations and definitions.

      A union can have member functions (including constructors and destructors), but not virtual functions.

      A union cannot have base classes and cannot be used as a base class.

      At most onevariant member can have adefault member initializer.

      (since C++11)

      A union cannot have non-static data members of reference types.

      Unions cannot contain a non-static data member with a non-trivialspecial member function.

      (until C++11)

      If a union contains a non-static data member with a non-trivialspecial member function, the corresponding special member function of the union may be defined as deleted, see the corresponding special member function page for details.

      (since C++11)

      Just like instruct declaration, the default member access in a union ispublic.

      [edit]Explanation

      The union is at least as big as necessary to hold its largest data member, but is usually not larger. The other data members are intended to be allocated in the same bytes as part of that largest member. The details of that allocation are implementation-defined, except that all non-static data members have the same address. It is undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union.

      Run this code
      #include <cstdint>#include <iostream> union S{std::int32_t n;// occupies 4 bytesstd::uint16_t s[2];// occupies 4 bytesstd::uint8_t c;// occupies 1 byte};// the whole union occupies 4 bytes int main(){    S s={0x12345678};// initializes the first member, s.n is now the active member// At this point, reading from s.s or s.c is undefined behavior,// but most compilers define it.std::cout<<std::hex<<"s.n = "<< s.n<<'\n';     s.s[0]=0x0011;// s.s is now the active member// At this point, reading from s.n or s.c is undefined behavior,// but most compilers define it.std::cout<<"s.c is now "<<+s.c<<'\n'// 11 or 00, depending on platform<<"s.n is now "<< s.n<<'\n';// 12340011 or 00115678}

      Possible output:

      s.n = 12345678s.c is now 0s.n is now 115678

      Each member is allocated as if it is the only member of the class.

      If members of a union are classes with user-defined constructors and destructors, to switch the active member, explicit destructor and placement new are generally needed:

      Run this code
      #include <iostream>#include <string>#include <vector> union S{std::string str;std::vector<int> vec;    ~S(){}// needs to know which member is active, only possible in union-like class};// the whole union occupies max(sizeof(string), sizeof(vector<int>)) int main(){    S s={"Hello, world"};// at this point, reading from s.vec is undefined behaviorstd::cout<<"s.str = "<< s.str<<'\n';    s.str.~basic_string();    new(&s.vec)std::vector<int>;// now, s.vec is the active member of the union    s.vec.push_back(10);std::cout<< s.vec.size()<<'\n';    s.vec.~vector();}

      Output:

      s.str = Hello, world1
      (since C++11)

      If two union members arestandard-layout types, it's well-defined to examine their common subsequence on any compiler.

      [edit]Member lifetime

      Thelifetime of a union member begins when the member is made active. If another member was active previously, its lifetime ends.

      When active member of a union is switched by an assignment expression of the formE1 = E2 that uses either the built-in assignment operator or a trivial assignment operator, for each union member X that appears in the member access and array subscript subexpressions ofE1 that is not a class with non-trivial or deleted default constructors, if modification of X would have undefined behavior under type aliasing rules, an object of the type of X is implicitly created in the nominated storage; no initialization is performed and the beginning of its lifetime is sequenced after the value computation of the left and right operands and before the assignment.

      union A{int x;int y[4];};struct B{ A a;};union C{ B b;int k;}; int f(){    C c;// does not start lifetime of any union member    c.b.a.y[3]=4;// OK: "c.b.a.y[3]", names union members c.b and c.b.a.y;// This creates objects to hold union members c.b and c.b.a.yreturn c.b.a.y[3];// OK: c.b.a.y refers to newly created object} struct X{constint a;int b;};union Y{ X x;int k;}; void g(){    Y y={{1,2}};// OK, y.x is active union memberint n= y.x.a;    y.k=4;// OK: ends lifetime of y.x, y.k is active member of union    y.x.b= n;// undefined behavior: y.x.b modified outside its lifetime,// "y.x.b" names y.x, but X's default constructor is deleted,// so union member y.x's lifetime does not implicitly start}

      Trivialmove constructor, move assignment operator,(since C++11)copy constructor and copy assignment operator of union types copy object representations. If the source and the destination are not the same object, these special member functions start lifetime of every object (except for objects that are neither subobjects of the destination nor ofimplicit-lifetime type) nested in the destination corresponding to the one nested in the source before the copy is performed. Otherwise, they do nothing. Two union objects have the same corresponding active member (if any) after construction or assignment via trivial special functions.

      [edit]Anonymous unions

      Ananonymous union is an unnamed union definition that does not simultaneously define any variables (including objects of the union type, references, or pointers to the union).

      union{member-specification};

      Anonymous unions have further restrictions: they cannot have member functions, cannot have static data members, and all their data members must be public. The only declarations allowed are non-static data members andstatic_assert declarations(since C++11).

      Members of an anonymous union are injected in the enclosing scope (and must not conflict with other names declared there).

      int main(){union{int a;constchar* p;};    a=1;    p="Jennifer";}

      Namespace-scope anonymous unions must be declaredstatic unless they appear in an unnamed namespace.

      [edit]Union-like classes

      Aunion-like class is either a union, or a (non-union) class that has at least one anonymous union as a member. A union-like class has a set ofvariant members :

      • the non-static data members of its member anonymous unions;
      • in addition, if the union-like class is a union, its non-static data members that are not anonymous unions.

      Union-like classes can be used to implementtagged union.

      Run this code
      #include <iostream> // S has one non-static data member (tag), three enumerator members (CHAR, INT, DOUBLE),// and three variant members (c, i, d)struct S{enum{CHAR, INT, DOUBLE} tag;union{char c;int i;double d;};}; void print_s(const S& s){switch(s.tag){case S::CHAR:std::cout<< s.c<<'\n';break;case S::INT:std::cout<< s.i<<'\n';break;case S::DOUBLE:std::cout<< s.d<<'\n';break;}} int main(){    S s={S::CHAR,'a'};    print_s(s);    s.tag= S::INT;    s.i=123;    print_s(s);}

      Output:

      a123

      The C++ standard library includesstd::variant, which can replace many uses of unions and union-like classes. The example above can be re-written as

      Run this code
      #include <iostream>#include <variant> int main(){std::variant<char,int,double> s='a';std::visit([](auto x){std::cout<< x<<'\n';}, s);    s=123;std::visit([](auto x){std::cout<< x<<'\n';}, s);}

      Output:

      a123
      (since C++17)

      [edit]Keywords

      union

      [edit]Defect reports

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

      DRApplied toBehavior as publishedCorrect behavior
      CWG 1940C++11anonymous unions only allowed non-static data membersstatic_assert also allowed

      [edit]References

      • C++23 standard (ISO/IEC 14882:2024):
      • 11.5 Unions [class.union]
      • C++20 standard (ISO/IEC 14882:2020):
      • 11.5 Unions [class.union]
      • C++17 standard (ISO/IEC 14882:2017):
      • 12.3 Unions [class.union]
      • C++14 standard (ISO/IEC 14882:2014):
      • 9.5 Unions [class.union]
      • C++11 standard (ISO/IEC 14882:2011):
      • 9.5 Unions [class.union]
      • C++03 standard (ISO/IEC 14882:2003):
      • 9.5 Unions [class.union]
      • C++98 standard (ISO/IEC 14882:1998):
      • 9.5 Unions [class.union]

      [edit]See also

      (C++17)
      a type-safe discriminated union
      (class template)[edit]
      C documentation forUnion declaration
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/union&oldid=180960"

      [8]ページ先頭

      ©2009-2025 Movatter.jp