这是一个代码片段,希望传达我正在尝试做的事情:
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*&)’
答案 0 :(得分: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(或等效的)。所以编译器必须拒绝这段代码。禁止const int*&
绑定到int*
是上面代码中唯一适合编译器拒绝的地方:每隔一行都没问题。
这与您无法将int**
隐式转换为const int **
的原因相同。
除了const-safety方面的动机之外,您可以认为int*
与const int*
的类型不同,恰好可以转换为int
。同样,您可以将double
转换为double&
,但int
无法绑定到int*
左值。这不是完整的原因,因为实际上const int*
和int
具有相同的大小和表示,而double
和strchr
则没有。因此,如果不是因为它会破坏const系统,可能会有一个特殊情况允许它。
C ++同时具有updatePointer
的const和非const重载的原因与此问题有关:函数strchr
修改其输入而不是返回更新的值,但原理类似。 C风格的单updatePointer
允许你将一个指向const的指针“清洗”到一个没有强制转换的指针到非const,这是const系统中的一个漏洞。 C ++(a)有重载,(b)有一个比C更严格的系统,所以它关闭了那个洞。
如果你希望你的真实函数strchr
像strchr
一样工作 - 检查指向的数据并为指针计算一个新值,那么你的情况与{{1}相同是的。这与新值的作用无关(在strchr
的情况下返回它,在updatePointer
的情况下将其写回),因为问题是您希望新指针具有与输入相同的const限定。您需要提供const和非const重载或函数模板。
如果您只需要实际函数updatePointer
将指针移动一定距离,无论指向哪个数据,都可以使用std::advance
代替。
答案 1 :(得分:5)
你写的是一个引用指向const int的指针的函数。你要求的是
updatePointer(int* const & i);
然而,这没有多大意义。传递对指针的引用似乎意味着您打算修改指针,但是您不能这样做,因为它被声明为const。因为它只是通过传递指针来获得相同的效果,如
updatePointer(int* i);
答案 2 :(得分:1)
Found this 如果以后链接中断,请复制此处:
这个推理有点尴尬。主要问题是: 自从“const int&”可以绑定到“int”,为什么不能“const int *&”被绑定到“int *”?
基本上,一旦添加了间接级别(指针),规则就会改变。只有一个间接级别(如单个*),规则可以表示为:
对指向cv限定类型的指针的引用可以绑定到cv-qualifications小于或等于指针(它是引用)的相同类型的任何类型。 (阅读几次。)
所以“const int *&”的原因不能绑定到“int *”是因为“const int *”和“int *”是两种不同的类型(规则的下划线部分被破坏)。