sashoalm
sashoalm

Reputation: 79457

error C2665: 'cv::fillPoly' : none of the 2 overloads could convert all the argument types

I get this strange error, where this code compiles (and displays a triangle correctly):

Point pts[3] = { Point(20, 20), Point(60, 20), Point(40, 40) };
const Point *ptsp = pts;
int npts[1] = {3};  
fillPoly(img, &ptsp, npts, 1, Scalar(255, 255, 0));

But if I replace const Point *ptsp = pts; with Point *ptsp = pts, then I get this error:

1>C:\Workspace\ImageProcessing\Tutorials\src\main.cpp(16): error C2665: 'cv::fillPoly' : none of the 2 overloads could convert all the argument types
1>          C:\Workspace\ImageProcessing\opencv\build\include\opencv2/core/core.hpp(2632): could be 'void cv::fillPoly(cv::Mat &,const cv::Point **,const int *,int,const cv::Scalar &,int,int,cv::Point)'
1>          C:\Workspace\ImageProcessing\opencv\build\include\opencv2/core/core.hpp(2637): or       'void cv::fillPoly(cv::InputOutputArray,cv::InputArrayOfArrays,const cv::Scalar &,int,int,cv::Point)'
1>          while trying to match the argument list '(cv::Mat, cv::Point **, int [1], int, cv::Scalar_<_Tp>)'
1>          with
1>          [
1>              _Tp=double
1>          ]

But normally you should be able to pass non-const pointers where the function expects a const pointer, so why does it fail to work here?

I had used Point *ptsp = pts; at first, of course, and it took me quite some time and head-scratching to figure out it needs to be const, and it was totally unexpected for me.

Upvotes: 0

Views: 2876

Answers (1)

Eric Lemanissier
Eric Lemanissier

Reputation: 367

This is explained here : http://www.parashift.com/c++-faq-lite/constptrptr-conversion.html

The reason the conversion from Foo** → Foo const** is dangerous is that it would let you silently and accidentally modify a const Foo object without a cast: class Foo { public: void modify(); // make some modification to the this object };

int main()
{
  const Foo x;
  Foo* p;
  Foo const** q = &p;  // q now points to p; this is (fortunately!) an error
  *q = &x;             // p now points to x
  p->modify();         // Ouch: modifies a const Foo!!
  ...
}

If the q = &p line were legal, q would be pointing at p. The next line, *q = &x, changes p itself (since q is p) to point at x. That would be a bad thing, since we would have lost the const qualifier: p is a Foo but x is a const Foo. The p->modify() line exploits p's ability to modify its referent, which is the real problem, since we ended up modifying a const Foo.

Upvotes: 1

Related Questions