Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Member access operators

      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
       
      Expressions
      General
      Literals
      Operators
      Conversions
       

      Accesses a member of its operand.

        Operator name            Syntax          OverloadablePrototype examples (forclass T)
      Inside class definitionOutside class definition
      subscripta[b]YesR& T::operator[](S b);N/A
      a[...](since C++23)R& T::operator[](...);
      indirection*aYesR& T::operator*();R& operator*(T a);
      address-of&aYesR* T::operator&();R* operator&(T a);
      member of objecta.b NoN/AN/A
      member of pointera->bYesR* T::operator->();N/A
      pointer to member of objecta.*b NoN/AN/A
      pointer to member of pointera->*bYesR& T::operator->*(S b);R& operator->*(T a, S b);
      Notes
      • As with most user-defined overloads, return types should match return types provided by the built-in operators so thatthe user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return type (includingvoid). One exception isoperator->, which must return a pointer or another class with overloadedoperator-> to be realistically usable.

      Contents

      [edit]Explanation

      Built-insubscript operator provides access to an object pointed-to by thepointer orarray operand.

      Built-inindirection operator provides access to an object or function pointed-to by the pointer operand.

      Built-inaddress-of operator creates a pointer pointing to the object or function operand.

      Member of object andpointer to member of object operators provide access to a data member or member function of the object operand.

      Built-inmember of pointer andpointer to member of pointer operators provide access to a data member or member function of the class pointed-to by the pointer operand.

      [edit]Built-in subscript operator

      The subscript operator expressions have the form

      expr1 [expr2 ] (1)
      expr1 [{expr , ...}] (2)(since C++11)
      expr1 [expr2 ,expr , ...] (3)(since C++23)
      1) For the built-in operator, one of the expressions (eitherexpr1 orexpr2) must be a glvalue of type “array ofT” or a prvalue of type “pointer toT”, while the other expression (expr2 orexpr1, respectively) must be a prvalue of unscoped enumeration or integral type. The result of this expression has the typeT.expr2 cannot be an unparenthesizedcomma expression.(since C++23)
      2) The form with brace-enclosed list inside the square brackets is only used to call an overloadedoperator[].
      3) The form with comma-separated expression list inside the square brackets is only used to call an overloadedoperator[].

      The built-in subscript expressionE1[E2] is exactly identical to the expression*(E1+ E2) except for its value category (see below) andevaluation order(since C++17): the pointer operand (which may be a result of array-to-pointer conversion, and which must point to an element of some array or one past the end) is adjusted to point to another element of the same array, following the rules ofpointer arithmetic, and is then dereferenced.

      When applied to an array, the subscript expression is anlvalue if the array is an lvalue, and anxvalue if it isn't(since C++11).

      When applied to a pointer, the subscript expression is always an lvalue.

      The typeT is not allowed to be anincomplete type, even if the size or internal structure ofT is never used, as in&x[0].

      Using an unparenthesizedcomma expression as second (right) argument of a subscript operator is deprecated.

      For example,a[b, c] is deprecated anda[(b, c)] is not.

      (since C++20)
      (until C++23)

      An unparenthesizedcomma expression cannot be second (right) argument of a subscript operator. For example,a[b, c] is either ill-formed or equivalent toa.operator[](b, c).

      Parentheses are needed to for using a comma expression as the subscript, e.g.,a[(b, c)].

      (since C++23)

      Inoverload resolution against user-defined operators, for every object typeT (possibly cv-qualified), the following function signature participates in overload resolution:

      T& operator[](T*,std::ptrdiff_t);
      T& operator[](std::ptrdiff_t, T*);
      Run this code
      #include <iostream>#include <map>#include <string> int main(){int a[4]={1,2,3,4};int* p=&a[2];std::cout<< p[1]<< p[-1]<<1[p]<<(-1)[p]<<'\n'; std::map<std::pair<int,int>,std::string> m;    m[{1,2}]="abc";// uses the [{...}] version}

      Output:

      4242

      [edit]Built-in indirection operator

      The indirection operator expressions have the form

      *expr

      The operand of the built-in indirection operator must be pointer to object or a pointer to function, and the result is the lvalue referring to the object or function to whichexpr points. Ifexpr does not actually points to an object or function, the behavior is undefined (except for the case specified bytypeid).

      A pointer to (possiblycv-qualified)void cannot be dereferenced. Pointers to other incomplete types can be dereferenced, but the resulting lvalue can only be used in contexts that allow an lvalue of incomplete type, e.g. when initializing a reference.

      Inoverload resolution against user-defined operators, for every typeT that is either object type (possibly cv-qualified) or function type (not const- or ref-qualified), the following function signature participates in overload resolution:

      T& operator*(T*);
      Run this code
      #include <iostream> int f(){return42;} int main(){int n=1;int* pn=&n; int& r=*pn;// lvalue can be bound to a referenceint m=*pn;// indirection + lvalue-to-rvalue conversion int(*fp)()=&f;int(&fr)()=*fp;// function lvalue can be bound to a reference [](...){}(r, m, fr);// removes possible "unused variable" warnings}

      [edit]Built-in address-of operator

      The address-of operator expressions have the form

      &expr (1)
      &class ::member (2)
      1) If the operand is an lvalue expression of some object or function typeT,operator& creates and returns a prvalue of typeT*, with the same cv qualification, that is pointing to the object or function designated by the operand. If the operand has incomplete type, the pointer can be formed, but if that incomplete type happens to be a class that defines its ownoperator&, it is unspecified whether the built-in or the overload is used. For the operands of type with user-definedoperator&,std::addressof may be used to obtain the true pointer.Note that, unlike C99 and later C versions, there's no special case for the unaryoperator& applied to the result of the unaryoperator*.
      If the operand is the name of an overloaded function, the address may be taken only if the overload can be resolved due to context. SeeAddress of an overloaded function for details.

      Ifexpr names anexplicit object member function,expr must be aqualified identifier. Applying& to an unqualified identifier naming an explicit object member function is ill-formed.

      (since C++23)
      2) If the operand is a qualified name of a non-static orvariant member other than anexplicit object member function(since C++23), e.g.&C::member, the result is a prvaluepointer to member function orpointer to data member of typeT in classC. Note that neither&member norC::member nor even&(C::member) may be used to initialize a pointer to member.

      Inoverload resolution against user-defined operators, this operator does not introduce any additional function signatures: built-in address-of operator does not apply if there exists an overloadedoperator& that is aviable function.

      Run this code
      void f(int){}void f(double){} struct A{int i;};struct B{void f();}; int main(){int n=1;int* pn=&n;// pointerint* pn2=&*pn;// pn2 == pn int A::* mp=&A::i;// pointer to data membervoid(B::*mpf)()=&B::f;// pointer to member function void(*pf)(int)=&f;// overload resolution due to initialization context//  auto pf2 = &f; // error: ambiguous overloaded function typeauto pf2=static_cast<void(*)(int)>(&f);// overload resolution due to cast}

      [edit]Built-in member access operators

      The member access operator expressions have the form

      expr .template(optional)id-expr (1)
      expr ->template(optional)id-expr (2)
      expr .pseudo-destructor (3)
      expr ->pseudo-destructor (4)
      1) Theexpr must be an expression ofcomplete class typeT.
      Ifid-expr names astatic member orenumerator,expr is adiscarded-value expression.
      2) Theexpr must be an expression of pointer to complete class typeT*.
      3,4) Theexpr must be an expression of scalar type (see below).

      id-expr is a name of (formally, anidentifier expression that names) a data member or member function ofT or of an unambiguous and accessible base classB ofT (e.g.E1.E2 orE1->E2), optionallyqualified (e.g.E1.B::E2 orE1->B::E2), optionally usingtemplate disambiguator (e.g.E1.template E2 orE1->template E2).

      If a user-definedoperator-> is called,operator-> is called again on the resulting value, recursively, until anoperator-> is reached that returns a plain pointer. After that, built-in semantics are applied to that pointer.

      The expressionE1->E2 is exactly equivalent to(*E1).E2 for built-in types; that is why the following rules address onlyE1.E2.

      In the expressionE1.E2:

      1) IfE2 is astatic data member:
      • IfE2 is of reference typeT&orT&&(since C++11), the result is an lvalue of typeT designating the object or function to which the reference is bound.
      • Otherwise, given the type ofE2 asT, the result is an lvalue of typeT designating that static data member.
      Essentially,E1 is evaluated and discarded in both cases.
      2) IfE2 is anon-static data member:
      • IfE2 is of reference typeT&orT&&(since C++11), the result is an lvalue of typeT designating the object or function to which the corresponding reference member ofE1 is bound.
      • Otherwise, ifE1 is an lvalue, the result is an lvalue designating that non-static data member ofE1.
      • Otherwise (ifE1 is anrvalue(until C++17)xvalue (which may bematerialized from prvalue)(since C++17)), the result is anrvalue(until C++11)xvalue(since C++11) designating that non-static data member ofE1.
      IfE2 is not amutable member, thecv-qualification of the result is the union of the cv-qualifications ofE1 andE2, otherwise (ifE2 is a mutable member), it is the union of the volatile-qualifications ofE1 andE2.
      3) IfE2 is an overload set (of one or morestatic member functions andnon-static member functions),E1.E2 must be the (possibly-parenthesized) left-hand operand of amember function call operator, andfunction overload resolution is used to select the function to whichE2 refers, after that:
      • IfE2 is astatic member function, the result is an lvalue designating that static member function. Essentially,E1 is evaluated and discarded in this case.
      • Otherwise (E2 is anon-static member function), the result is a prvalue designating that non-static member function ofE1.
      4) IfE2 is a member enumerator, given the type ofE2 asT, the result isan rvalue(until C++11)a prvalue(since C++11) of typeT whose value is the value of the enumerator.
      5) IfE2 is anested type, the program is ill-formed.
      6) IfE1 has aScalarType andE2 is a~ followed by thetype name ordecltype specifier designating the same type (minus cv-qualifications), optionallyqualified, the result is a special kind of prvalue that can only be used as the left-hand operand of a function call operator, and for no other purpose
      The resulting function call expression is calledpseudo destructor call. It takes no arguments, returnsvoid, evaluatesE1, and ends the lifetime of its result object. This is the only case where the left-hand operand ofoperator. has non-class type. Allowing pseudo destructor call makes it possible to write code without having to know if a destructor exists for a given type.

      operator. cannot be overloaded, and foroperator->, inoverload resolution against user-defined operators, the built-in operator does not introduce any additional function signatures: built-inoperator-> does not apply if there exists an overloadedoperator-> that is aviable function.

      Run this code
      #include <cassert>#include <iostream>#include <memory> struct P{template<typename T>static T* ptr(){return new T;}}; template<typename T>struct A{    A(int n): n(n){} int n;staticint sn; int f(){return10+ n;}staticint sf(){return4;} class B{};enum E{RED=1, BLUE=2}; void g(){typedefint U; // keyword template needed for a dependent template memberint* p= T().template ptr<U>();        p->~U();// U is int, calls int's pseudo destructor        delete p;}}; template<>int A<P>::sn=2; struct UPtrWrapper{std::unique_ptr<std::string> uPtr;std::unique_ptr<std::string>& operator->(){return uPtr;}}; int main(){    A<P> a(1);std::cout<< a.n<<' '<< a.sn<<' '// A::sn also works<< a.f()<<' '<< a.sf()<<' '// A::sf() also works//            << &a.f << ' '   // error: ill-formed if a.f is not the// left-hand operand of operator()//            << a.B << ' '    // error: nested type not allowed<< a.RED<<' ';// enumerator     UPtrWrapper uPtrWrap{std::make_unique<std::string>("wrapped")};assert(uPtrWrap->data()== uPtrWrap.operator->().operator->()->data());}

      Output:

      1 2 11 4 1

      IfE2 is a non-static member and the result ofE1 is an object whose type is notsimilar to the type ofE1, the behavior is undefined:

      struct A{int i;};struct B{int j;};struct D: A, B{}; void f(){    D d;static_cast<B&>(d).j;// OK, object expression designates the B subobject of dreinterpret_cast<B&>(d).j;// undefined behavior}

      [edit]Built-in pointer-to-member access operators

      The member access operator expressions through pointers to members have the form

      lhs .*rhs (1)
      lhs ->*rhs (2)
      1)lhs must be an expression of class typeT.
      2)lhs must be an expression of type pointer to class typeT*.

      rhs must be an rvalue of type pointer to member (data orfunction) ofT or pointer to member of an unambiguous and accessible base classB ofT.

      The expressionE1->*E2 is exactly equivalent to(*E1).*E2 for built-in types; that is why the following rules address onlyE1.*E2.

      In the expressionE1.*E2:

      1) ifE2 is a pointer to data member,
      • ifE1 is an lvalue, the result is an lvalue designating that data member,
      • otherwise (ifE1 is anrvalue(until C++17)xvalue (which may bematerialized from prvalue)(since C++17)), the result is anrvalue(until C++11)xvalue(since C++11) designating that data member;
      2) ifE2 is a pointer to member function, the result is a special kind of prvalue designating that member function that can only be used as the left-hand operand of a member function call operator, and for no other purpose;
      3) cv-qualification rules are the same as for member of object operator, with one additional rule: a pointer to member that refers to a mutable member cannot be used to modify that member in a const object;
      4) ifE2 is a null pointer-to-member value, the behavior is undefined;
      5) if the resultE1 is an object such that its type is notsimilar to the type ofE1, or itsmost derived object does not contain the member to whichE2 refers, the behavior is undefined;
      6) ifE1 is an rvalue andE2 points to a member function with ref-qualifier&, the program is ill-formedunless the member function has the cv-qualifierconst but notvolatile(since C++20);
      7) ifE1 is an lvalue andE2 points to a member function with ref-qualifier&&, the program is ill-formed.
      (since C++11)

      Inoverload resolution against user-defined operators, for every combination of typesD,B,R, where class typeB is either the same class asD or an unambiguous and accessible base class ofD, andR is either an object or function type, the following function signature participates in overload resolution:

      R& operator->*(D*, R B::*);

      where both operands may be cv-qualified, in which case the return type's cv-qualification is the union of the cv-qualification of the operands.

      Run this code
      #include <iostream> struct S{    S(int n): mi(n){}    mutableint mi;int f(int n){return mi+ n;}}; struct D:public S{    D(int n): S(n){}}; int main(){int S::* pmi=&S::mi;int(S::* pf)(int)=&S::f; const S s(7);//  s.*pmi = 10; // error: cannot modify through mutablestd::cout<< s.*pmi<<'\n';     D d(7);// base pointers work with derived object    D* pd=&d;std::cout<<(d.*pf)(7)<<' '<<(pd->*pf)(8)<<'\n';}

      Output:

      714 15

      [edit]Standard library

      Subscript operator is overloaded by many standard container classes:

      accesses specific bit
      (public member function ofstd::bitset<N>)[edit]
      provides indexed access to the managed array
      (public member function ofstd::unique_ptr<T,Deleter>)[edit]
      accesses the specified character
      (public member function ofstd::basic_string<CharT,Traits,Allocator>)[edit]
      access specified element
      (public member function ofstd::array<T,N>)[edit]
      access specified element
      (public member function ofstd::deque<T,Allocator>)[edit]
      access specified element
      (public member function ofstd::vector<T,Allocator>)[edit]
      access or insert specified element
      (public member function ofstd::map<Key,T,Compare,Allocator>)[edit]
      access or insert specified element
      (public member function ofstd::unordered_map<Key,T,Hash,KeyEqual,Allocator>)[edit]
      accesses an element by index
      (public member function ofstd::reverse_iterator<Iter>)[edit]
      accesses an element by index
      (public member function ofstd::move_iterator<Iter>)[edit]
      get/set valarray element, slice, or mask
      (public member function ofstd::valarray<T>)[edit]
      returns specified sub-match
      (public member function ofstd::match_results<BidirIt,Alloc>)[edit]

      The indirection and member operators are overloaded by many iterators and smart pointer classes:

      dereferences pointer to the managed object
      (public member function ofstd::unique_ptr<T,Deleter>)[edit]
      dereferences the stored pointer
      (public member function ofstd::shared_ptr<T>)[edit]
      accesses the managed object
      (public member function ofstd::auto_ptr<T>)[edit]
      dereferences the iterator
      (public member function ofstd::raw_storage_iterator<OutputIt,T>)[edit]
      dereferences the decremented underlying iterator
      (public member function ofstd::reverse_iterator<Iter>)[edit]
      no-op
      (public member function ofstd::back_insert_iterator<Container>)[edit]
      no-op
      (public member function ofstd::front_insert_iterator<Container>)[edit]
      no-op
      (public member function ofstd::insert_iterator<Container>)[edit]
      accesses the pointed-to element
      (public member function ofstd::move_iterator<Iter>)[edit]
      returns the current element
      (public member function ofstd::istream_iterator<T,CharT,Traits,Distance>)[edit]
      no-op
      (public member function ofstd::ostream_iterator<T,CharT,Traits>)[edit]
      obtains a copy of the current character
      (public member function ofstd::istreambuf_iterator<CharT,Traits>)[edit]
      no-op
      (public member function ofstd::ostreambuf_iterator<CharT,Traits>)[edit]
      accesses the current match
      (public member function ofstd::regex_iterator<BidirIt,CharT,Traits>)[edit]
      accesses current submatch
      (public member function ofstd::regex_token_iterator<BidirIt,CharT,Traits>)[edit]

      No standard library classes overloadoperator&. The best known example of overloadedoperator& is the Microsoft COM classCComPtr, although it can also appear in EDSLs such asboost.spirit.

      No standard library classes overloadoperator->*. It was suggested that it could be part ofsmart pointer interface, and in fact is used in that capacity by actors inboost.phoenix, but is more common in EDSLs such ascpp.react.

      [edit]Notes

      Feature-test macroValueStdFeature
      __cpp_multidimensional_subscript202110L(C++23)Multidimensional subscript operator

      [edit]Defect reports

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

      DRApplied toBehavior as publishedCorrect behavior
      CWG 1213C++11subscripting an array rvalue resulted in lvaluereclassified as xvalue
      CWG 1458C++98applying& to an lvalue of incomplete class type which
      declaresoperator& resulted in undefined behavior
      it is unspecified
      which& is used
      CWG 1642C++98therhs  in built-in pointer-to-member access operators could be an lvaluecan only be an rvalue
      CWG 1800C++98when applying& to a non-static data member of a
      member anonymous union, it was unclear whether
      the anonymous union take a part in the result type
      the anonymous union
      is not included in
      the result type
      CWG 2614C++98the result ofE1.E2 was unclear ifE2 is a reference member or enumeratormade clear
      CWG 2725C++98ifE2 is a static member function,E1.E2 is well-formed
      even if it is not the left hand opreand ofoperator()
      E1.E2 is ill-formed
      in this case
      CWG 2748C++98the behavior ofE1->E2 was unclear ifE1 is a
      null pointer andE2 refers to a static member
      the behavior is
      undefined in this case
      CWG 2813C++98E1 was not a discarded-value expression if
      E1.E2 names a static member or enumeration
      it is
      CWG 2823C++98the behavior of*expr was unclear ifexpr
      does not point to an object or function
      made clear

      [edit]See also

      Operator precedence

      Operator overloading

      Common operators
      assignmentincrement
      decrement
      arithmeticlogicalcomparisonmember
      access
      other

      a= b
      a+= b
      a-= b
      a*= b
      a/= b
      a%= b
      a&= b
      a|= b
      a^= b
      a<<= b
      a>>= b

      ++a
      --a
      a++
      a--

      +a
      -a
      a+ b
      a- b
      a* b
      a/ b
      a% b
      ~a
      a& b
      a| b
      a^ b
      a<< b
      a>> b

      !a
      a&& b
      a|| b

      a== b
      a!= b
      a< b
      a> b
      a<= b
      a>= b
      a<=> b

      a[...]
      *a
      &a
      a->b
      a.b
      a->*b
      a.*b

      function call

      a(...)
      comma

      a, b
      conditional

      a? b: c
      Special operators

      static_cast converts one type to another related type
      dynamic_cast converts within inheritance hierarchies
      const_cast adds or removescv-qualifiers
      reinterpret_cast converts type to unrelated type
      C-style cast converts one type to another by a mix ofstatic_cast,const_cast, andreinterpret_cast
      new creates objects with dynamic storage duration
      delete destructs objects previously created by the new expression and releases obtained memory area
      sizeof queries the size of a type
      sizeof... queries the size of apack(since C++11)
      typeid queries the type information of a type
      noexcept checks if an expression can throw an exception(since C++11)
      alignof queries alignment requirements of a type(since C++11)

      C documentation forMember access operators
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/operator_member_access&oldid=172326"

      [8]ページ先頭

      ©2009-2025 Movatter.jp