Why can C++ const references be collasped into non-const references

蓝咒 提交于 2020-01-03 08:39:47

问题


Consider the following C++ program:

#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';
}

The program compiles OK and outputs 43. This suggests that the seemingly const reference returned by get() is in fact a non-const reference, because it allows to modifies the value it refers to.

Is it a rule of reference collapsing that causes this behaviour?

How to enforce that the reference returned from get() behaves like a const reference, that is, it doesn't allow to modify the value it refers to?


回答1:


Is it a rule of reference collapsing that causes this behaviour?

Yes. You have:

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

References can't be const (you can't rebind them anyways, so it's ignored) and a reference to a reference is just a reference.

So you have

const T& = int&

To fix this, you need to apply const to the underlying type, which you can do like this by removing the reference:

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


来源:https://stackoverflow.com/questions/50336279/why-can-c-const-references-be-collasped-into-non-const-references

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!