4

这是一个代码片段,希望能传达我正在尝试做的事情:

void updatePointer(const int*& i)
{
  i++;
}

int main() {


  int array[5];
  int* arrayPtr = array;

  updatePointer(arrayPtr );
  return 0;
}

这会产生编译器错误:

prog.cpp: In function ‘int main()’:
prog.cpp:16: error: invalid initialization of reference of type ‘const int*&’ from
expression of type ‘int*’
prog.cpp:5: error: in passing argument 1 of ‘void updatePointer(const int*&)’
4

3 回答 3

6

假设您可以做到,您可以编写以下内容:

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*,那么它恰好可以转换为它。同样,您可以转换intdouble,但 adouble&不能绑定到int左值。这不是全部原因,因为实际上int*const int*具有相同的大小和表示,而intdouble不具有相同的大小和表示。因此,如果不是因为它会破坏 const 系统,那么可能会有一个特殊情况允许它。

C++ 有 const 和 non-const 重载的strchr原因与这个问题有关:你的函数updatePointer修改了它的输入而不是返回更新的值,但原理是相似的。C 风格的单曲strchr允许您将指向 const 的指针“洗白”成指向非 const 的指针而无需强制转换,这是 const 系统中的一个漏洞。C++ (a) 具有重载,并且 (b) 具有比 C 更严格的类型系统,因此它填补了这个漏洞。

如果您希望您的真实函数updatePointerstrchr- 检查指向的数据并为指针计算一个新值,那么您处于相同的情况strchr。这与它对新值的作用无关(在 的情况下返回它,在 的情况下strchr将其写回updatePointer),因为问题是您希望新指针具有与输入相同的 const 限定。您需要提供 const 和非常量重载或函数模板。

如果您只需要真正的函数updatePointer将指针移动一定距离,无论指向的数据如何,您都可以使用std::advance

于 2012-09-26T11:32:37.957 回答
5

你写的是一个函数,它引用一个指向 const int 的指针。你要求的是

updatePointer(int* const & i);

然而,这没有多大意义。传递对指针的引用似乎意味着您打算修改指针,但您不能这样做,因为它被声明为 const。实际上,您只需传递指针即可获得相同的效果

updatePointer(int* i);
于 2012-09-26T11:00:05.850 回答
1

发现这个 复制在这里,以防将来链接中断:

这个推理有点尴尬。主要问题是:既然“const int&”可以绑定到“int”,为什么“const int*&”不能绑定到“int*”?

基本上,一旦添加了间接级别(指针),规则就会改变。仅使用一个间接级别(如在单个 * 中),该规则可以表述为:

对指向 cv 限定类型的指针的引用可以绑定到 cv 限定小于或等于指针(即引用)的任何相同类型。(多读几遍。)

所以“const int*&”不能绑定到“int*”的原因是因为“const int*”和“int*”是两种不同的类型(规则的下划线部分被破坏)。

于 2012-09-26T11:02:08.227 回答