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 | ||||||||||||||||||||||||||
| ||||||||||||||||||||||||||
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 | ||||||||||||||||
Binds a reference to an object.
Contents |
T & ref= target; T | (1) | ||||||||
T && ref= target; T | (2) | (since C++11) | |||||||
func-refpar( target) | (3) | ||||||||
return target; | (4) | (inside the definition offunc-refret ) | |||||||
Class:: Class( ...) : ref-member( target) { ...} | (5) | (inside the definition ofClass ) | |||||||
T & ref= { arg1, arg2, ...}; T | (1) | ||||||||
T && ref= { arg1, arg2, ...}; T | (2) | ||||||||
func-refpar({ arg1, arg2, ...}); | (3) | ||||||||
T & ref= {. des1= arg1, . des2{ arg2} ...}; T | (1) | ||||||||
T && ref= {. des1= arg1, . des2{ arg2} ...}; T | (2) | ||||||||
func-refpar({. des1= arg1, . des2{ arg2} ...}); | (3) | ||||||||
A reference toT
can be initialized with an object of typeT
, a function of typeT
, or an object implicitly convertible toT
. Once initialized, a reference cannot be reseated (changed) to refer to another object.
References are initialized in the following situations:
T | - | the referenced type |
ref | - | the reference variable to be initialized |
target | - | the initializer expression being used |
func-refpar | - | a function with a parameter of reference type (T & orT && (since C++11)) |
func-refret | - | a function whose returns type is a reference type (T & orT && (since C++11)) |
Class | - | a class name |
ref-member | - | a non-static data member of reference type (T & orT && (since C++11)) ofClass |
des1,des2, ... | - | designators |
arg1,arg2, ... | - | the initializers in initializer lists |
For two typesT1
andT2
:
T1
andT2
asU1
andU2
respectively, ifU1
issimilar toU2
, orU1
is abase class ofU2
,T1
isreference-related toT2
.T2
” can be converted to the type “pointer toT1
” via a standard conversion sequence,T1
isreference-compatible withT2
.If a reference initialization uses an ordinary or designated(since C++20) list-initialization, the rules oflist-initialization are followed. | (since C++11) |
For non-list reference initialization, given the type oftarget asU
, the reference eitherbinds directly totarget or binds to a value of typeT
converted fromtarget. Direct binding is considered first, followed by indirect binding, if neither binding is available, the program is ill-formed.
In all cases where the reference-compatible relationship of two types is used to establish the validity of a reference binding and the standard conversion sequence would be ill-formed, a program that necessitates such a binding is ill-formed.
If all following conditions are satisfied:
T
is reference-compatible withU
.Then the reference binds totarget, or to its appropriate base class subobject:
double d=2.0;double& rd= d;// rd refers to dconstdouble& rcd= d;// rcd refers to d struct A{};struct B: A{} b; A& ra= b;// ra refers to A subobject in bconst A& rca= b;// rca refers to A subobject in b
Otherwise, if all following conditions are satisfied:
U
is a class type.T
is not reference-related toU
.V
such thatT
is reference-compatible withV
.Then the reference binds to the lvalue result of the conversion, or to its appropriate base class subobject:
struct A{};struct B: A{ operatorint&();}; int& ir= B();// ir refers to the result of B::operator int&
Otherwise, if the reference to be initialized is an lvalue reference, andT
is not const-qualified or is volatile-qualified, the prorgram is ill-formed:
double& rd2=2.0;// error: not an lvalue and reference is not constint i=2;double& rd3= i;// error: type mismatch and reference is not const
Otherwise, if all following conditions are satisfied:
| (until C++11) |
| (since C++11) (until C++17) |
| (since C++17) |
T
is reference-compatible withU
.Then the reference binds totarget, or to its appropriate base class subobject:
struct A{};struct B: A{};extern B f(); const A& rca2= f();// bound to the A subobject of the B rvalue.A&& rra= f();// same as above int i2=42;int&& rri=static_cast<int&&>(i2);// bound directly to i2
Iftarget is a prvalue,temporary materialization is applied to it, considering the type of the prvalue to be the adjusted type
In this case, the reference binds to the result object, or to its appropriate base class subobject. | (since C++17) |
Otherwise, if all following conditions are satisfied:
U
is a class type.T
is not reference-related toU
.V
such thatT
is reference-compatible withV
, wherev is of any following category:
| (until C++11) |
| (since C++11) (until C++17) |
| (since C++17) |
Then the reference binds to the result of the conversion, or to its appropriate base class subobject:
struct A{};struct B: A{};struct X{ operator B();} x; const A& r= x;// bound to the A subobject of the result of the conversionB&& rrb= x;// bound directly to the result of the conversion
If the result of the conversion is a prvalue,temporary materialization is applied to it, considering the type of the prvalue to be the adjusted type
In this case, the reference binds to the result object, or to its appropriate base class subobject. | (since C++17) |
If direct binding is not available, indirect binding is considered. In this case,T
cannot be reference-related toU
.
IfT
orU
is a class type, user-defined conversions are considered using the rules forcopy-initialization of an object of typeT
by user-defined conversion. The program is ill-formed if the corresponding non-reference copy-initialization would be ill-formed. The result of the call to the conversion function, as described for the non-referencecopy-initialization, is then used to direct-initialize the reference. For this direct-initialization, user-defined conversions are not considered.
Otherwise, a temporary of type | (until C++17) |
Otherwise,target is implicitly converted to a prvalue of type “cv-unqualified | (since C++17) |
conststd::string& rs="abc";// rs refers to temporary copy-initialized from char arrayconstdouble& rcd2=2;// rcd2 refers to temporary with value 2.0int i3=2;double&& rrd3= i3;// rrd3 refers to temporary with value 2.0
Whenever a reference is bound to a temporary object or to a subobject thereof, the lifetime of the temporary object is extended to match the lifetime of the reference (checktemporary object lifetime exceptions), where the temporary object or its subobject is denoted by one of following expression:
| (until C++17) |
(since C++17) |
const_cast
,static_cast
,dynamic_cast
, orreinterpret_cast
conversion without a user-defined conversion that converts one of these expressions to the glvalue refers to the object designated by the operand, or to its complete object or a subobject thereof (anexplicit cast expression is interpreted as a sequence of these casts),There are following exceptions to this lifetime rule:
| (until C++26) |
| (since C++11) |
struct A{int&& r;}; A a1{7};// OK, lifetime is extendedA a2(7);// well-formed, but dangling reference | (since C++20) |
In general, the lifetime of a temporary cannot be further extended by "passing it on": a second reference, initialized from the reference variable or data member to which the temporary was bound, does not affect its lifetime.
References appear without initializers only in function parameter declaration, in function return type declaration, in the declaration of a class member, and with theextern
specifier.
Until the resolution ofCWG issue 1696, a temporary is permitted to bound to a reference member in a constructorinitializer list, and it persists only until the constructor exits, not as long as the object exists. Such initialization is ill-formed sinceCWG 1696, although many compilers still support it (a notable exception is clang).
#include <sstream>#include <utility> struct S{int mi;conststd::pair<int,int>& mp;// reference member}; void foo(int){} struct A{}; struct B: A{int n; operatorint&(){return n;}}; B bar(){return B();} //int& bad_r; // error: no initializerexternint& ext_r;// OK int main(){// Lvaluesint n=1;int& r1= n;// lvalue reference to the object nconstint& cr(n);// reference can be more cv-qualifiedvolatileint& cv{n};// any initializer syntax can be usedint& r2= r1;// another lvalue reference to the object n// int& bad = cr; // error: less cv-qualifiedint& r3=const_cast<int&>(cr);// const_cast is needed void(&rf)(int)= foo;// lvalue reference to functionint ar[3];int(&ra)[3]= ar;// lvalue reference to array B b; A& base_ref= b;// reference to base subobjectint& converted_ref= b;// reference to the result of a conversion // Rvalues// int& bad = 1; // error: cannot bind lvalue ref to rvalueconstint& cref=1;// bound to rvalueint&& rref=1;// bound to rvalue const A& cref2= bar();// reference to A subobject of B temporary A&& rref2= bar();// same int&& xref=static_cast<int&&>(n);// bind directly to n// int&& copy_ref = n; // error: can't bind to an lvaluedouble&& copy_ref= n;// bind to an rvalue temporary with value 1.0 // Restrictions on temporary lifetimes// std::ostream& buf_ref = std::ostringstream() << 'a';// the ostringstream temporary was bound to the left operand// of operator<< but its lifetime ended at the semicolon so// the buf_ref is a dangling reference S a{1,{2,3}};// temporary pair {2, 3} bound to the reference member// a.mp and its lifetime is extended to match// the lifetime of object a S* p= new S{1,{2,3}};// temporary pair {2, 3} bound to the reference// member p->mp, but its lifetime ended at the semicolon// p->mp is a dangling reference delete p; // Imitate [[maybe_unused]] applied to the following variables:[](...){}( cv, r2, r3, rf, ra, base_ref, converted_ref, a, cref, rref, cref2, rref2, copy_ref, xref);}
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 391 | C++98 | initialize a reference to const-qualified type with a class type rvalue might create a temporary, and a constructor of that class was required in order to copy the rvalue into that temporary | no temporary is created, constructor is not required |
CWG 450 | C++98 | a reference to const-qualified array could not be initialized with a reference-compatible array rvalue | allowed |
CWG 589 | C++98 | a reference could not bind directly to an array or class rvalue | allowed |
CWG 656 | C++98 | a reference to const-qualified type initialized with a type which is not reference-compatible but has a conversion function to a reference- compatible type was bound to a temporary copied from the return value (or its base class subobject) of the conversion function | bound to the return value (or its base class subobject) directly |
CWG 1287 | C++11 | the conversion fromtarget of class type to another reference-compatible type could only be implicit | allow explicit conversions |
CWG 1295 | C++11 | a reference could bind to a bit-field xvalue | prohibited |
CWG 1299 | C++98 | the definition of temporary was unclear | made clear |
CWG 1571 | C++98 | user-defined conversions in indirect binding did not consider the type oftarget | considered |
CWG 1604 | C++98 | user-defined conversions were not considered in indirect binding | considered |
CWG 2352 | C++98 | reference compatibility did not consider qualification conversions | considered |
CWG 2481 | C++17 | cv-qualification was not added to the result type of temporary materialization in indirect binding | added |
CWG 2657 | C++17 | cv-qualification was not added to the result type of temporary materialization in direct binding | added |
CWG 2801 | C++98 | reference-related types were allowed for indirect binding | prohibited |