2010-03-17 191 views
23

我有一个接收float**作为参数的函数,我试图将其更改为const float**为什么我在将'float **'转换为'const float **'时出错?

编译器(g++)不喜欢它,并发出:

invalid conversion from ‘float**’ to ‘const float**’

这是没有意义的,我知道(和验证)我可以通过char*给接受const char*功能,那为什么不用const float**

回答

20

Why am I getting an error converting a Foo** → const Foo**?

由于转换Foo**const Foo**是非法且危险的......究其原因,从Foo**const Foo**转换是危险的是,它可以让你悄无声息,不小心修改一个const Foo对象,而不演员阵容

参考文献继续举例说明这种隐式转换如何允许我修改const对象而无需强制转换。

+3

也许一个总结会增加更多的答案。 – GManNickG 2010-03-17 15:23:26

18

这是一个非常棘手的限制。它与语言的别名规则有关。看看标准说什么,因为我已经遇到此之前曾经:

(第61页)

[注:如果一个程序可以一 指针类型的T **分配给指针 类型为const T **(也就是说,如果允许下面的行// 1 ),则程序可能会无意中修改常量对象 (因为它在行// 2上完成)。对于 例如,

int main() { 
    const char c = 'c'; 
    char* pc; 
    const char** pcc = &pc; //1: not allowed 
    *pcc = &c; 
    *pc = 'C'; //2: modifies a const object 
} 

就要收注]

8

如果转换的参数const float**然后你可以在存储器位置参数指向存储const float*。但是调用函数认为这个内存位置应该包含一个非const float*,并可能稍后尝试更改指向的这个float

因此,您不能将float**转换为const float**,它将允许您在指向可变值的指针所在的位置存储指向常量的指针。

详情请参阅C++ FAQ Lite

+0

+1 - 最佳答案。 – JonH 2010-03-17 15:33:16

10

其他anwers已详细说明为什么这是C++中的错误。

让我解决你的问题背后的问题。你想在你的函数的接口中声明你的函数不会修改数组中包含的浮点值。意图很好,并且可以使用const float **数组调用您的函数。你的问题背后的问题是,如何实现这一点,而不会解决丑陋的演员。

要达到目标的正确方法是将函数参数的类型更改为const float * const *

星号之间的附加const确保编译器确保您的方法不会尝试存储指向数组中const float的指针,因为此类型声明指针值也是const。

您现在可以使用float **(这是您的问题中的示例),const float **const float * const *参数调用此函数。

+0

是的。 const语法的规则是,如果它位于某个类型的左侧,它将紧密地绑定到它的右侧,否则它将修改它的左侧。因此'const int'和'int const'是相同的类型,'const int *'和'int const *'都是指向int的指针,const是const,'int * const'是一个指针,你不能改变为'int'你可以,'const int * const'和'int const * const'是你不能改变为'int'的指针,你不能改变。无限延伸。 – Ben 2013-10-18 15:09:34

+0

“实现你想要的正确方法是将函数参数的类型更改为const float * const *。”到底我在找什么,这个答案应该更高。 – 2017-01-28 20:52:29

+0

如果我使用签名'foo(const char ** bar)'调用API,该怎么办? 我无法控制API,我如何解决函数调用中的这个错误? – 2017-08-21 08:46:27