Search code examples
c++referenceconst-correctness

Why can I have a const pair<const T, T> reference to a pair<T, T>?


I found out by chance that I can have a const std::pair<const int, int>& reference to a std::pair<int,int>:

#include <utility>
int main()
{
    std::pair<int, int> p{1,2};
    const std::pair<const int, int>& ref_ok{p}; // why does this work?
    std::pair<const int, int>& ref_invalid{p}; // then why does this not work?
}

Why is this possible, considering that const std::pair<const int, int> and std::pair<int, int> are different types that are not related by inheritance?


Solution

  • const std::pair<const int, int>& ref_ok{p}; is actually materializing a temporary std::pair<const int, int> initialized to the same values as p and the reference initialization is extending the lifetime of the temporary to that of the lifetime of the reference.

    std::pair<const int, int>& ref_invalid{p}; is not allowed because non-const references can't bind to a temporary.

    The following code example shows that ref_ok is not actually a reference to p. Changes to p have no effect on ref_ok.

    #include <iostream>
    #include <utility>
    
    int main()
    {
        std::pair<int,int> p{1,2};
        const std::pair<const int, int>& ref_ok{p}; // why does this work?
    
        std::cout << p.first << ' ' << ref_ok.first << '\n';
    
        p.first = 5;
    
        std::cout << p.first << ' ' << ref_ok.first << '\n';
    }
    

    Output :

    1 1
    5 1
    

    Live example : https://godbolt.org/z/8bfM7fYbx