Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Reference 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
       
      Declarations
       

      Declares a named variable as a reference, that is, an alias to an already-existing object or function.

      Contents

      [edit]Syntax

      A reference variable declaration is any simple declaration whosedeclarator has the form

      &attr (optional)declarator (1)
      &&attr (optional)declarator (2)(since C++11)
      1)Lvalue reference declarator: the declarationS& D; declaresD as anlvalue reference to the type determined bydecl-specifier-seqS.
      2)Rvalue reference declarator: the declarationS&& D; declaresD as anrvalue reference to the type determined bydecl-specifier-seqS.
      declarator - anydeclarator except for reference declarator,array declarator, andpointer declarator (there are no references to references, arrays of references, or pointers to references)
      attr -(since C++11) list ofattributes

      A reference is required to be initialized to refer to a valid object or function: seereference initialization.

      The type “reference to (possibly cv-qualified)void” cannot be formed.

      Reference types cannot becv-qualified at the top level; there is no syntax for that in declaration, and if a qualification is added to a typedef-name ordecltype specifier,(since C++11) ortype template parameter, it is ignored.

      References are not objects; they do not necessarily occupy storage, although the compiler may allocate storage if it is necessary to implement the desired semantics (e.g. a non-static data member of reference type usually increases the size of the class by the amount necessary to store a memory address).

      Because references are not objects, there are no arrays of references, no pointers to references, and no references to references:

      int& a[3];// errorint&* p;// errorint&&r;// error

      Reference collapsing

      It is permitted to form references to references through type manipulations in templates or typedefs, in which case thereference collapsing rules apply: rvalue reference to rvalue reference collapses to rvalue reference, all other combinations form lvalue reference:

      typedefint&  lref;typedefint&& rref;int n; lref&  r1= n;// type of r1 is int&lref&& r2= n;// type of r2 is int&rref&  r3= n;// type of r3 is int&rref&& r4=1;// type of r4 is int&&

      (This, along with special rules fortemplate argument deduction whenT&& is used in a function template, forms the rules that makestd::forward possible.)

      (since C++11)

      [edit]Lvalue references

      Lvalue references can be used to alias an existing object (optionally with different cv-qualification):

      Run this code
      #include <iostream>#include <string> int main(){std::string s="Ex";std::string& r1= s;conststd::string& r2= s;     r1+="ample";// modifies s//  r2 += "!";               // error: cannot modify through reference to conststd::cout<< r2<<'\n';// prints s, which now holds "Example"}

      They can also be used to implement pass-by-reference semantics in function calls:

      Run this code
      #include <iostream>#include <string> void double_string(std::string& s){    s+= s;// 's' is the same object as main()'s 'str'} int main(){std::string str="Test";    double_string(str);std::cout<< str<<'\n';}

      When a function's return type is lvalue reference, the function call expression becomes anlvalue expression:

      Run this code
      #include <iostream>#include <string> char& char_number(std::string& s,std::size_t n){return s.at(n);// string::at() returns a reference to char} int main(){std::string str="Test";    char_number(str,1)='a';// the function call is lvalue, can be assigned tostd::cout<< str<<'\n';}

      Rvalue references

      Rvalue references can be used toextend the lifetimes of temporary objects (note, lvalue references to const can extend the lifetimes of temporary objects too, but they are not modifiable through them):

      Run this code
      #include <iostream>#include <string> int main(){std::string s1="Test";//  std::string&& r1 = s1;           // error: can't bind to lvalue conststd::string& r2= s1+ s1;// okay: lvalue reference to const extends lifetime//  r2 += "Test";                    // error: can't modify through reference to const std::string&& r3= s1+ s1;// okay: rvalue reference extends lifetime    r3+="Test";// okay: can modify through reference to non-conststd::cout<< r3<<'\n';}

      More importantly, when a function has both rvalue reference and lvalue referenceoverloads, the rvalue reference overload binds to rvalues (including both prvalues and xvalues), while the lvalue reference overload binds to lvalues:

      Run this code
      #include <iostream>#include <utility> void f(int& x){std::cout<<"lvalue reference overload f("<< x<<")\n";} void f(constint& x){std::cout<<"lvalue reference to const overload f("<< x<<")\n";} void f(int&& x){std::cout<<"rvalue reference overload f("<< x<<")\n";} int main(){int i=1;constint ci=2;     f(i);// calls f(int&)    f(ci);// calls f(const int&)    f(3);// calls f(int&&)// would call f(const int&) if f(int&&) overload wasn't provided    f(std::move(i));// calls f(int&&) // rvalue reference variables are lvalues when used in expressionsint&& x=1;    f(x);// calls f(int& x)    f(std::move(x));// calls f(int&& x)}

      This allowsmove constructors,move assignment operators, and other move-aware functions (e.g.std::vector::push_back()) to be automatically selected when suitable.

      Because rvalue references can bind to xvalues, they can refer to non-temporary objects:

      int i2=42;int&& rri= std::move(i2);// binds directly to i2

      This makes it possible to move out of an object in scope that is no longer needed:

      std::vector<int> v{1,2,3,4,5};std::vector<int> v2(std::move(v));// binds an rvalue reference to vassert(v.empty());

      Forwarding references

      Forwarding references are a special kind of references that preserve the value category of a function argument, making it possible toforward it by means ofstd::forward. Forwarding references are either:

      1) function parameter of a function template declared as rvalue reference to cv-unqualifiedtype template parameter of that same function template:
      template<class T>int f(T&& x)// x is a forwarding reference{return g(std::forward<T>(x));// and so can be forwarded} int main(){int i;    f(i);// argument is lvalue, calls f<int&>(int&), std::forward<int&>(x) is lvalue    f(0);// argument is rvalue, calls f<int>(int&&), std::forward<int>(x) is rvalue} template<class T>int g(const T&& x);// x is not a forwarding reference: const T is not cv-unqualified template<class T>struct A{template<class U>    A(T&& x, U&& y,int* p);// x is not a forwarding reference: T is not a// type template parameter of the constructor,// but y is a forwarding reference};
      2)auto&& except when deduced from a brace-enclosed initializer list or, when representing a template parameter of a class template duringclass template argument deduction(since C++17):
      auto&& vec= foo();// foo() may be lvalue or rvalue, vec is a forwarding referenceauto i=std::begin(vec);// works either way(*i)++;// works either way g(std::forward<decltype(vec)>(vec));// forwards, preserving value category for(auto&& x: f()){// x is a forwarding reference; this is a common way to use range for in generic code} auto&& z={1,2,3};// *not* a forwarding reference (special case for initializer lists)

      See alsotemplate argument deduction andstd::forward.

      (since C++11)

      [edit]Dangling references

      Although references always refer to valid objects or functions upon initialization, it is possible to create a program where thelifetime of the referred-to object ends, but the reference remains accessible (dangling).

      Given an expressionexpr of reference type and lettarget be the object or function denoted by the reference:

      • If a pointer totarget would bevalid in the context of the evalution ofexpr, the result designatestarget.
      • Otherwise, the behavior is undefined.
      std::string& f(){std::string s="Example";return s;// exits the scope of s:// its destructor is called and its storage deallocated} std::string& r= f();// dangling referencestd::cout<< r;// undefined behavior: reads from a dangling referencestd::string s= f();// undefined behavior: copy-initializes from a dangling reference

      Note that rvalue references and lvalue references to const extend the lifetimes of temporary objects (seeReference initialization for rules and exceptions).

      If the referred-to object was destroyed (e.g., by explicit destructor call), but the storage was not deallocated, a reference to the out-of-lifetime object may be used in limited ways, and may become valid if the object is recreated in the same storage (seeAccess outside of lifetime for details).

      [edit]Type-inaccessible references

      Attempting to bind a reference to an object where the converted initializer isan lvalue(until C++11)a glvalue(since C++11) through which the object is nottype-accessible results in undefined behavior:

      char x alignas(int); int& ir=*reinterpret_cast<int*>(&x);// undefined behavior:// initializer refers to char object

      [edit]Call-incompatible references

      Attempting to bind a reference to a function where the converted initializer isan lvalue(until C++11)a glvalue(since C++11) whose type is notcall-compatible with the type of the function's definition results in undefined behavior:

      void f(int); using F=void(float);F& ir=*reinterpret_cast<F*>(&f);// undefined behavior:// initializer refers to void(int) function

      [edit]Notes

      Feature-test macroValueStdFeature
      __cpp_rvalue_references200610L(C++11)Rvalue references

      [edit]Defect reports

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

      DRApplied toBehavior as publishedCorrect behavior
      CWG 453C++98it was unclear which object or function a reference cannot be bound tomade clear
      CWG 1510C++11cv-qualified references could not be formed in the operand ofdecltypeallowed
      CWG 2550C++98parameters could have type “reference tovoiddisallowed
      CWG 2933C++98the behavior of accessing dangling references was unclearmade clear

      [edit]External links

      Thomas Becker, 2013 -C++ Rvalue References Explained
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/reference&oldid=183388"

      [8]ページ先頭

      ©2009-2025 Movatter.jp