Reference initialization

Binds a reference to an object.

# Notes

References appear without initializers only in function parameter declaration, in function return type declaration, in the declaration of a class member, and with the extern specifier.

Until the resolution of CWG issue 1696, a temporary is permitted to bound to a reference member in a constructor initializer list, and it persists only until the constructor exits, not as long as the object exists. Such initialization is ill-formed since CWG 1696, although many compilers still support it (a notable exception is clang).

# Example

#include <sstream>
#include <utility>
 
struct S
{
    int mi;
    const std::pair<int, int>& mp; // reference member
};
 
void foo(int) {}
 
struct A {};
 
struct B : A
{
    int n;
    operator int&() { return n; }
};
 
B bar() { return B(); }
 
//int& bad_r;      // error: no initializer
extern int& ext_r; // OK
 
int main()
{
//  Lvalues
    int n = 1;
    int& r1 = n;                    // lvalue reference to the object n
    const int& cr(n);               // reference can be more cv-qualified
    volatile int& cv{n};            // any initializer syntax can be used
    int& r2 = r1;                   // another lvalue reference to the object n
//  int& bad = cr;                  // error: less cv-qualified
    int& r3 = const_cast<int&>(cr); // const_cast is needed
 
    void (&rf)(int) = foo; // lvalue reference to function
    int ar[3];
    int (&ra)[3] = ar;     // lvalue reference to array
 
    B b;
    A& base_ref = b;        // reference to base subobject
    int& converted_ref = b; // reference to the result of a conversion
 
//  Rvalues
//  int& bad = 1;        // error: cannot bind lvalue ref to rvalue
    const int& cref = 1; // bound to rvalue
    int&& 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 lvalue
    double&& 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
    );
}

# Defect reports

DRApplied toBehavior as publishedCorrect behavior
CWG 391C++98initialize a reference to const-qualified type with a class typervalue might create a temporary, and a constructor of that classwas required in order to copy the rvalue into that temporaryno temporary iscreated, constructoris not required
CWG 450C++98a reference to const-qualified array could not beinitialized with a reference-compatible array rvalueallowed
CWG 589C++98a reference could not bind directly to an array or class rvalueallowed
CWG 656C++98a reference to const-qualified type initialized with a type which is notreference-compatible but has a conversion function to a reference-compatible type was bound to a temporary copied from the returnvalue (or its base class subobject) of the conversion functionbound to the returnvalue (or its base classsubobject) directly
CWG 1287C++11the conversion from target of class type to anotherreference-compatible type could only be implicitallow explicitconversions
CWG 1295C++11a reference could bind to a bit-field xvalueprohibited
CWG 1299C++98the definition of temporary was unclearmade clear
CWG 1571C++98user-defined conversions in indirectbinding did not consider the type of targetconsidered
CWG 1604C++98user-defined conversions were not considered in indirect bindingconsidered
CWG 2352C++98reference compatibility did not consider qualification conversionsconsidered
CWG 2481C++17cv-qualification was not added to the result typeof temporary materialization in indirect bindingadded
CWG 2657C++17cv-qualification was not added to the result typeof temporary materialization in direct bindingadded
CWG 2801C++98reference-related types were allowed for indirect bindingprohibited

# See also