Initializing References

Variables of reference type must be initialized with an object of the type from which the reference type is derived, or with an object of a type that can be converted to the type from which the reference type is derived. For example:

// initializing_references.cpp
int iVar;
long lVar;
int main() {
   long& LongRef1 = lVar;   // No conversion required.
   long& LongRef2 = iVar;   // C2440
   const long& LongRef3 = iVar;   // OK
   LongRef1 = 23L;   // Change lVar through a reference.
   LongRef2 = 11L;   // Change iVar through a reference.
   LongRef3 = 11L;   // C3892
}

The only way to initialize a reference with a temporary object is to initialize a constant temporary object. Once initialized, a reference-type variable always points to the same object; it cannot be modified to point to another object.

Although the syntax can be the same, initialization of reference-type variables and assignment to reference-type variables are semantically different. In the preceding example, the assignments that change iVar and lVar look similar to the initializations, but have different effects. The initialization specifies the object to which the reference-type variable points; the assignment assigns to the referred-to object through the reference.

Because both passing an argument of reference type to a function and returning a value of reference type from a function are initializations, the formal arguments to a function are initialized correctly, as are the references returned.

Reference-type variables can be declared without initializers only in the following:

  • Function declarations (prototypes). For example:

    int func( int& );
    
  • Function-return type declarations. For example:

    int& func( int& );
    
  • Declaration of a reference-type class member. For example:

    class c {
    public:
       int& i;
    };
    
  • Declaration of a variable explicitly specified as extern. For example:

    extern int& iVal;
    

When initializing a reference-type variable, the compiler uses the decision graph shown in the following figure to select between creating a reference to an object or creating a temporary object to which the reference points.

Decision Graph for Initialization of Reference Types
Decision Graph Initalization Reference Types

References to volatile types (declared as volatile typename**&** identifier) can be initialized with volatile objects of the same type or with objects that have not been declared as volatile. They cannot, however, be initialized with const objects of that type. Similarly, references to const types (declared as const typename**&** identifier) can be initialized with const objects of the same type (or anything that has a conversion to that type or with objects that have not been declared as const). They cannot, however, be initialized with volatile objects of that type.

References that are not qualified with either the const or volatile keyword can be initialized only with objects declared as neither const nor volatile.

See Also

Concepts

Initializers