Dear Experts,

This is a question about Boost.Polygon but please keep reading

even if you've never used that library as it's really just about

how to resolve ambiguous template specialisations.

Boost.Polygon has a mechanism by which you can tell it about

your own types by specialising templates. I want to tell it that

std::array<Point,N> is a polygon, which I try to do like this:

template <size_t N>

struct geometry_concept< std::array<Point,N> >

{

using type = polygon_concept;

};

template <size_t N>

struct polygon_traits< std::array<Point,N> >

{ ....... };

This doesn't work because of ambiguity between that specialisation

of polygon_traits and a default specialization that is in the library

itself; the library code looks something like this:

template <typename T, typename enable = gtl_yes>

struct polygon_traits {};

template <typename T>

struct polygon_traits<T, ...some SFINAE stuff.... >

{ ......... };

If I try to just specialize one size of array it works:

template <>

struct polygon_traits< std::array<g2i::Point,3> >

{ ....... };

The error is:

test_template_specialization.cc:64:19: error: ambiguous partial specializations of 'polygon_traits<std::__1::array<Point, 3>, boost::polygon::gtl_yes>'

boost::polygon::polygon_traits<std::array<Point,3>>::iterator_type i = nullptr;

^

/usr/local/include/boost/polygon/polygon_traits.hpp:100:10: note: partial specialization matches [with T = std::__1::array<Point, 3>]

struct polygon_traits<T,

^

test_template_specialization.cc:32:8: note: partial specialization matches [with N = 3]

struct polygon_traits< std::array<Point,N> >

^

I have the same issue when I attempt to use a Point class that

takes the coordinate type as a template parameter.

Can anyone suggest how I can write my specialisations so that they

are unambiguous?

A complete test program follows. I'm testing with Boost 1.69.0, but

I don't think anything has changed in Polygon since then.

Thanks, Phil.

#include <boost/polygon/polygon.hpp>

#include <array>

struct Point { int x; int y; };

namespace boost { namespace polygon {

template <>

struct geometry_concept<Point>

{

using type = point_concept;

};

template <>

struct point_traits<Point>

{

using coordinate_type = int;

static inline coordinate_type get(const Point& point, orientation_2d orient)

{

return (orient==HORIZONTAL) ? point.x : point.y;

}

};

template <size_t N>

struct geometry_concept< std::array<Point,N> >

{

using type = polygon_concept;

};

template <size_t N>

struct polygon_traits< std::array<Point,N> >

{

using coordinate_type = int;

using iterator_type = typename std::array<Point,N>::const_iterator;

using point_type = Point;

static inline iterator_type begin_points(const std::array<Point,N>& p)

{

return p.begin();

}

static inline iterator_type end_points(const std::array<Point,N>& p)

{

return p.end();

}

static inline std::size_t size(const std::array<Point,N>&)

{

return N;

}

static inline winding_direction winding(const std::array<Point,N>&)

{

return unknown_winding; // Hmm.

}

};

}; }; // namespace boost, polygon

int main()

{

boost::polygon::polygon_traits<std::array<Point,3>>::iterator_type i = nullptr;

return 0;

}

_______________________________________________

Boost-users mailing list

[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users