注意const Type **引起的Compile Error

Edit on Github

问题

这个问题是在写计算机视觉的作业时发现的,使用OpenCV2.0库的C++ API来计算图像直方图,程序如下:

int bins = 256;
int histSize[] = { bins };
float granges[] = {0, 255};
float* ranges[] = { granges };
int channels[] = { 0 };

calcHist(&gray, 1, channels, Mat(), // do not use mask
    hist, 1, histSize, ranges<<NOTE HERE>>);

可是提示:

error C2665: 'cv::calcHist' : none of the 2 overloads could convert all the argument types
......
while trying to match the argument list '(cv::Mat *, int, int [1], cv::Mat, cv::MatND, int, int [1], float *[1], bool, bool)'

calcHist 声明有两个

CV_EXPORTS void calcHist( const Mat* images, int nimages,
                          const int* channels, const Mat&mask,
                          MatND&hist, int dims, const int* histSize,
                          const float** ranges, bool uniform=true,
                          bool accumulate=false );

CV_EXPORTS void calcHist( const Mat* images, int nimages,
                          const int* channels, const Mat&mask,
                          SparseMat&hist, int dims, const int* histSize,
                          const float** ranges, bool uniform=true,
                          bool accumulate=false );

可是都没法匹配

尝试

calcHist 的每个参数进行强制类型转换,luckly,我从后面开始

calcHist(&gray, 1, channels, Mat(), // do not use mask
    hist, 1, histSize, (const float**)ranges<<NOTE HERE>>);

这样是可以的,但下面就不行了。

calcHist(&gray, 1, channels, Mat(), // do not use mask
    hist, 1, histSize, const_cast<float**>(ranges)<<NOTE HERE>>);

分析

参考《Effective c++》Item21上的做法,如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。 也就是说上面的 const float** ranges 中 ranges 不是 const,ranges[i] 才是const,但这还是没法说明问题。等以后考虑了。。。

参考

为什么 char** 不能自动转化为 const char** 1.

  1. 《Effective c++》