user2004519 user2004519 - 1 year ago 48
C++ Question

Calling modifiers of a deque by reference in a function produce MinGW64 compile errors

I'm passing a variable

std::deque<cv::Point[4]> pastpolygons
by reference. I'm also passing the C array
cv::Point polygon[4]
by reference to the same function. The intention is that the one function may push/pop the array into the
of arrays as needed. I've written the code how I think it should work ( is there any other way to write code? ) and the compile errors are pretty verbose and hard to understand (it's several pages).

Here's the code:

void AveragePolygon ( cv::Point (*polygon)[4], std::deque<cv::Point[4]> *pastpolygons, int samplestokeep )
pastpolygons->push_back( *polygon ); //comment and compiles fine
if ( pastpolygons->size() > samplestokeep ) {
pastpolygons->pop_front(); //comment and compiles fine

The parameter and argument syntax was particularly tricky, but it compiles so long as I don't try to call the modifiers of
. I've also tried
instead, to no avail. Any ideas?

Also, the first bit of the compile errors:

C:/MinGW64/x86_64-w64-mingw32/include/c++/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = cv::Point_<int> [4]; _Args = {const cv::Point_<int> (&)[4]}; _Tp = cv::Point_<int> [4]]': C:/MinGW64/x86_64-w64-mingw32/include/c++/bits/alloc_traits.h:256:4: required from 'static std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = cv::Point_<int> [4]; _Args = {const cv::Point_<int> (&)[4]}; _Alloc = std::allocator<cv::Point_<int> [4]>; std::_Require<typename s

Answer Source

Well, I feel the need to say
that when you are on C++, and especially nowadays c++11
you can forget about pointers, and rock it using
high level programming! (which is super efficient!
That's the beauty of C++).

So to our busyness, I would define a polygon to be:

typedef vector<cv::Point> Polygon;

And then comes the rest:

void AveragePolygons(Polygon polygon, deque<Polygon> &pastpolygons)
    pastpolygons.push_back(polygon);   //comment and compiles fine
    if (pastpolygons.size() > samplestokeep ) {
        pastpolygons.pop_front();         //comment and compiles fine

When working like this,
I believe the problems you experience will be gone,
since many of them relate to pointers, shallow copying, etc..

One more thing,
if you want to make sure a polygon consists of 4 points only
you can derive it from a vector and provide the proper
constructor or other member functions to ensure this.

For example, the following obsessively-c++11 code
defines a constructor which takes 4 points:

struct Polygon : public vector<cv::Point> {
    Polygon(cv::Point p1, cv::Point p2, cv::Point p3, cv::Point p4) :
        vector<cv::Point>{p1, p2, p3, p4}