Почему C ++ константные ссылки могут быть объединены в неконстантные ссылки - PullRequest
0 голосов
/ 14 мая 2018

Рассмотрим следующую программу на C ++:

#include <iostream>

template<typename T>
class A
{
public:
    explicit A(T& x) : x_(x){}
    const T& get() { return x_; }

private:
    T x_;
};

int main()
{
    int x = 42;
    A<int&>(x).get() = 43; // compiles fine, even though get() looks like it returns a const ref
    std::cout << x << '\n';
}

Программа компилирует OK и выводит 43. Это говорит о том, что на первый взгляд константная ссылка, возвращаемая get (), на самом деле является неконстантной reference, поскольку он позволяет изменять значение, на которое он ссылается.

Это правило свертывания ссылок вызывает такое поведение?

Как обеспечить, чтобы ссылка, возвращаемая из get (), действовалакак ссылка на const, то есть она не позволяет изменять значение, на которое она ссылается?

1 Ответ

0 голосов
/ 14 мая 2018

Это правило свертывания ссылок вызывает такое поведение?

Да . У вас есть:

T = int&
const T& = const (int&) &

Ссылки не могут быть const (вы не можете их связать в любом случае, поэтому они игнорируются), а ссылка на ссылку - это просто ссылка.

Итак, у вас есть

const T& = int&

Чтобы исправить это, вам нужно применить const к базовому типу, что вы можете сделать так, удалив ссылку:

const std::remove_reference_t<T>& get() { return x_; }
//    ^^^^^^^^^^^^^^^^^^^^^^^
...