2012-09-26 29 views
4

这里有一个代码片段希望传达我想要做的事:为什么不能传递一个非const的指针,采取一个指针引用一个const作为参数的函数

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

我觉得你不能得到const的非const引用 – Yola

+0

我决定删除我的答案,因为我不确定你在问什么。 –

+0

我基本上问为什么不会上面的代码编译 – Fenster34

回答

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 int*&绑定到int*是上述代码中唯一适合编译器拒绝的地方:每隔一行都可以。

这与您无法将int**隐式转换为const int **的原因相同。

除了在const-safety方面的动机之外,你可以认为它是否与是不同类型的const int*,它恰好可以转换为它。同样,你可以转换到intdouble,但double&不能绑定到int左值。这不是完整的原因,因为实际上int*const int*具有相同的大小和表示,而intdouble不具有。因此,如果不是因为它会打破const系统,那么可能会有一个特殊情况。

C++对strchr有const和non-const超载的原因与此问题有关:您的函数updatePointer修改其输入,而不是返回更新的值,但原理类似。 C风格的单机版strchr允许你在没有强制转换的情况下将指向const的指针“洗”到指向非const的指针中,这是const系统中的一个漏洞。 C++(a)有重载和(b)有比C更严格的类型系统,所以它关闭了这个漏洞。

如果你希望你的真正功能updatePointerstrchr工作 - 检查所指向的数据和计算新的价值,为指针,那么你在同样的情况是strchr是。这与新值无关(在strchr的情况下返回,在updatePointer的情况下将其重新写回),因为问题是您希望新指针与输入具有相同的常量限定。您需要提供常量和非常量重载或函数模板。

如果您只需要实际功能updatePointer将指针移动一定的距离,无论指向哪个数据,都可以使用std::advance代替。

5

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

updatePointer(int* const & i); 

然而这没有多大意义。传递对指针的引用似乎意味着你打算修改指针,但是你不能这样做,因为它被声明为const。因为它是你的只是路过你的指针在

updatePointer(int* i); 
+0

对不起,我在问题标题中犯了一个错误,在发布之前没有得到更新的机会 – Fenster34

1

Found this 这里复制的情况下,链接中断在未来得到同样的效果:

的理由是有点别扭来交手用。主要的问题是: 因为“const int的&”可以绑定到一个“诠释”,为什么不能在“const int的* &”绑定到“诠释*”?

基本上,一旦你增加一个间接(指针)的水平,那么规则的改变。只有一个间接级别(如在单个*中),规则可以表述为:

对指向cv限定类型的指针的引用可以绑定到同一类型的任何其cv-qualifications小于或等于指针(它是参考)的指针。

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

相关问题