【问题标题】:Binding const T (&ref)[N] to object of type T[N]将 const T (&ref)[N] 绑定到 T[N] 类型的对象
【发布时间】:2016-09-09 22:54:12
【问题描述】:

我注意到奇怪的语义 wrt 绑定对指针和数组的引用,它们分别在指向和数组元素的常量上不同。使用指针可以预见地失败:

int* p{};
const int*& p_ref{p};

non-const lvalue reference to type 'const int *' cannot bind to a  value of unrelated type 'int *'

有道理,pointer-to-int 和pointer-to-const-int 是两种不同的类型,在& 之前添加const 允许编译器生成一个临时的,它可以工作,但不会改变以上。

但是,我认为应该与数组类似的不是

int arr[5]{};
const int (&arr_ref)[5]{arr};

clang 和 gcc 都毫无怨言地编译了上面的代码,但是为什么呢?我将对const int[5] 的非常量引用绑定到int[5] 类型的对象。为什么允许这样做?

更新: Gotcha #32(第 82 页)在 Stephen C. Dewhurst 的 C++ Gotchas 中描述了类似的问题

【问题讨论】:

标签: c++ arrays pointers c++11 reference


【解决方案1】:

对于您的第一个示例,如果允许,则可能会破坏 const 正确性。

int *p{};
const int*& p_ref{p}; // pretend this is okay
const int x = 10;
p_ref = &x;           // storing the address of a const int in a const int*, okay
*p = 5;               // Should be okay, because p is int*, not const int*,
                      // but oops, just modified a const value

对数组的引用没有这个问题,因为你不能将数组指向其他地方(因为它不是指针)。

指针的指针也有类似的问题。通常情况下,我们将非常量T 的地址存储在const T* 中。因为这没关系,人们倾向于认为应该可以将T* 的地址存储在const T** 中。但这会导致与上述参考示例相同的问题:

int* p;
const int** pp = &p;  // forbidden, but pretend it's okay for now
const int x = 10;
*pp = &x;              // storing the address of a const int in a const int*, okay
*p = 5;                // oops, modified a const int

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    相关资源
    最近更新 更多