Ask Your Question
1

Nothrow move constructors for Point, Size, Point3, Rect

asked 2015-12-08 12:51:43 -0500

Charles Tallman gravatar image

The static asserts currently fail with opencv-3.0.0 with gcc (GCC) 5.1.1 20150618 (Red Hat 5.1.1-4)

#include <type_traits>                  // for is_nothrow_move_constructible
#include <vector>                       // for vector
#include "opencv2/core/types.hpp"       // for Point2d, Rect2d, etc.

struct x_polyline {
    cv::Point2d start;
    std::vector<double> polyline;

    x_polyline(const x_polyline&) = default;
    x_polyline(x_polyline&& rhs) = default;
};

int main()
{
    static_assert(std::is_nothrow_move_constructible<cv::Point2d>::value, "cv::Point2d move constructor could throw");
    static_assert(std::is_nothrow_move_constructible<cv::Point3d>::value, "cv::Point3d move constructor could throw");
    static_assert(std::is_nothrow_move_constructible<cv::Size2d>::value, "cv::Size2d move constructor could throw");
    static_assert(std::is_nothrow_move_constructible<cv::Rect2d>::value, "cv::Rect2d move constructor could throw");

    static_assert(std::is_nothrow_move_constructible<x_polyline>::value, "x_polyline move constructor could throw");

    return 0;
}

The current hand-written copy constructors for these simple classes block the compiler from generating its own move constructors. As the example above shows, this applies to any class that includes them. Such classes will be hard to use in a std::vector, which decides whether to move or copy its contents on reallocation by testing this type trait (using std::move_if_noexcept).

If the copy constructors for cv::Point_, cv::Size_, cv::Point3_ and cv::Rect_ are commented out, or set to "= default", then the asserts will not fail. Would it be possible to do this for a future release of openCV?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-08-29 14:53:47 -0500

Charles Tallman gravatar image

Not a perfect solution, but I created my own simple geometric types that can be converted to and from the cv types. For example:

namespace nice {
template<typename _Tp> class NicePoint_
{

public:
constexpr NicePoint_();
constexpr NicePoint_(_Tp _x, _Tp _y);

// Regular and move constructors
constexpr NicePoint_(const NicePoint_& rhs) = default;
NicePoint_(NicePoint_&& rhs) noexcept;

// Regular and move assignment
NicePoint_& operator=(const NicePoint_& rhs) = default;
NicePoint_& operator=(NicePoint_&& rhs) noexcept;

// Allow back-and-forth conversion to cv::Point_
NicePoint_(cv::Point_<_Tp>) noexcept;
operator cv::Point_<_Tp>() const noexcept;

// Dot product
_Tp dot(const NicePoint_ & pt) const;

// Dot product in double precision
double ddot(const NicePoint_ & pt) const;

// Cross product
double cross(const NicePoint_ & pt) const;

template<typename _U>
NicePoint_ scale(const _U &s) const
{
    return NicePoint_(x * s, y * s);
}; 

_Tp x, y; //< the point coordinates
};

typedef NicePoint_<int> Point2i;
typedef NicePoint_<float> Point2f;
typedef NicePoint_<double> Point2d;
typedef Point2i Point;
} // end of namespace nice
edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2015-12-08 12:51:43 -0500

Seen: 238 times

Last updated: Aug 29 '16