假设您可以做到,您可以编写以下内容:
const int c = 0;
void updatePointer(const int* &i) {
i = &c;
}
int main() {
int *ptr;
updatePointer(ptr);
*ptr = 1; // attempt to modify the const object c, undefined behavior
}
的目的const
是确保用户代码不能尝试修改 const 对象,除非它包含 const-cast(或等效项)。所以编译器不得不拒绝这段代码。禁止 aconst int*&
绑定到 anint*
是上面代码中编译器合理拒绝的唯一地方:每隔一行都可以。
这与您不能隐式转换int**
为const int **
.
除了 const-safety 方面的动机之外,您可以认为如果它int*
是与 不同的类型const int*
,那么它恰好可以转换为它。同样,您可以转换int
为double
,但 adouble&
不能绑定到int
左值。这不是全部原因,因为实际上int*
和const int*
具有相同的大小和表示,而int
和double
不具有相同的大小和表示。因此,如果不是因为它会破坏 const 系统,那么可能会有一个特殊情况允许它。
C++ 有 const 和 non-const 重载的strchr
原因与这个问题有关:你的函数updatePointer
修改了它的输入而不是返回更新的值,但原理是相似的。C 风格的单曲strchr
允许您将指向 const 的指针“洗白”成指向非 const 的指针而无需强制转换,这是 const 系统中的一个漏洞。C++ (a) 具有重载,并且 (b) 具有比 C 更严格的类型系统,因此它填补了这个漏洞。
如果您希望您的真实函数updatePointer
像strchr
- 检查指向的数据并为指针计算一个新值,那么您处于相同的情况strchr
。这与它对新值的作用无关(在 的情况下返回它,在 的情况下strchr
将其写回updatePointer
),因为问题是您希望新指针具有与输入相同的 const 限定。您需要提供 const 和非常量重载或函数模板。
如果您只需要真正的函数updatePointer
将指针移动一定距离,无论指向的数据如何,您都可以使用std::advance
。