Weird compilation error when using boost::geometry

Hi, I have implemented my own "point" as specified by the point concept http://www.boost.org/doc/libs/1_59_0/libs/geometry/doc/html/geometry/referen... When I use it along with boost::geometry::model::polygon/multi_polygon, GCC refuses to compile, tested on GCC 4.9/5.2. What's even more weird is that CLANG 3.6 would happy accept my code. BTW, the Point implementation is part of a large project, it difficult to replace it with boost::geometry::model::point. Here is my code: Point.hpp
#ifndef RAPTOR_POINT_HPP_INCLUDED_
#define RAPTOR_POINT_HPP_INCLUDED_
#include <boost/mpl/int.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
namespace raptor {
template<typename T, int tDimension = 2>
class Point {
public:
Point() = default;
Point(T a, T b) {
data[0] = a;
data[1] = b;
}
Point(T a, T b, T c) {
data[0] = a;
data[1] = b;
data[2] = c;
}
T& operator [] (long index) {
return data[index];
}
const T& operator [] (long index) const {
return data[index];
}
private:
T data[tDimension];
};
using CubicPoint = Point<long, 3>;
using PlanarPoint = Point<long>;
using SphericalPoint = Point<double>;
template<typename T>
using Polygon = boost::geometry::model::polygon<T>;
template<typename T>
using PolySet = boost::geometry::model::multi_polygon<Polygon<T>>;
} // namespace raptor
namespace boost { namespace geometry { namespace traits {
template<typename Type, std::size_t tDimension>
struct tag<::raptor::Point<Type, tDimension>> {
typedef point_tag type;
};
template<typename Type, std::size_t tDimension>
struct coordinate_type<::raptor::Point<Type, tDimension>> {
typedef Type type;
};
template<typename Type, std::size_t tDimension>
struct coordinate_system<::raptor::Point<Type, tDimension>> {
typedef boost::geometry::cs::cartesian type;
};
template<typename Type, std::size_t tDimension>
struct dimension<::raptor::Point<Type, tDimension>>
: public boost::mpl::int_<tDimension> {
// EMPTY
};
template<typename Type, std::size_t tDimension, std::size_t tIndex>
struct access<::raptor::Point<Type, tDimension>, tIndex> {
static Type get(const ::raptor::Point<Type, tDimension>& p) {
return p[tIndex];
}
static void set(::raptor::Point<Type, tDimension>& p,
const Type& value) {
p[tIndex] = value;
}
};
}}} // namespace boost::geometry::traits
#endif // RAPTOR_POINT_HPP_INCLUDED_
A real simple main.cpp:
#include "Point.hpp"
int main() {
raptor::Polygon<raptor::SphericalPoint> pl;
raptor::PolySet<raptor::SphericalPoint> set;
return sizeof(pl) + sizeof(set);
}
GCC compilation error: g++ main.cpp -std=c++14
In file included from /usr/include/boost/geometry/core/access.hpp:20:0,
from Point.hpp:5, from main.cpp:1: /usr/include/boost/geometry/core/point_type.hpp: In instantiation of
'struct boost::geometry::traits::point_type<raptor::Point<double> >':
/usr/include/boost/geometry/core/point_type.hpp:66:17: required from
'struct boost::geometry::core_dispatch::point_type<void, raptor::Point<double> >'
/usr/include/boost/geometry/core/coordinate_type.hpp:58:62: required from
'struct boost::geometry::core_dispatch::coordinate_type<void, raptor::Point<double> >'
/usr/include/boost/geometry/core/coordinate_type.hpp:92:25: required from
'struct boost::geometry::coordinate_type<raptor::Point<double> >'
/usr/include/boost/geometry/geometries/concepts/point_concept.hpp:90:54:
required from 'class boost::geometry::concept::Point<raptor::Point<double>
'
/usr/include/boost/concept/detail/has_constraints.hpp:32:62: required by
substitution of 'template<class Model> boost::concepts::detail::yes boost::concepts::detail::has_constraints_(Model*, boost::concepts::detail::wrap_constraints<Model, (& Model:: constraints)>*) [with Model = boost::geometry::concept::Point<raptor::Point<double> >]'
/usr/include/boost/concept/detail/has_constraints.hpp:42:5: required from
'const bool boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double>
::value'
/usr/include/boost/concept/detail/has_constraints.hpp:45:31: required
from 'struct boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double>
'
/usr/include/boost/mpl/if.hpp:67:11: required from 'struct
boost::mpl::if_<boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double>
, boost::concepts::constraint<boost::geometry::concept::Point<raptor::Point<double> , boost::concepts::requirement<boost::concepts::failed************ boost::geometry::concept::Point<raptor::Point<double> >::************> >'
/usr/include/boost/concept/detail/general.hpp:50:8: required from 'struct
boost::concepts::requirement_<void (*)(boost::geometry::concept::Point<raptor::Point<double> >)>'
/usr/include/boost/geometry/geometries/ring.hpp:60:5: required from
'class boost::geometry::model::polygon<raptor::Point<double>, true, true, std::vector, std::vector, std::allocator, std::allocator>'
main.cpp:4:42: required from here /usr/include/boost/geometry/core/point_type.hpp:45:5: error: no matching
function for call to 'assertion_failed(mpl_::failed************ (boost::geometry::traits::point_type<raptor::Point<double>
::NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE::************)(mpl_::assert_::types<raptor::Point<double>, mpl_::na, mpl_::na, mpl_::na>))'
BOOST_MPL_ASSERT_MSG ^ /usr/include/boost/mpl/assert.hpp:82:5: note: candidate: template<bool C>
int mpl_::assertion_failed(typename mpl_::assert<C>::type)
int assertion_failed( typename assert<C>::type ); ^ /usr/include/boost/mpl/assert.hpp:82:5: note: template argument
deduction/substitution failed:
/usr/include/boost/geometry/core/point_type.hpp:45:5: note: cannot
convert 'boost::geometry::traits::point_type<Geometry>::NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE48::assert_arg<raptor::Point<double>
()' (type 'mpl_::failed************ (boost::geometry::traits::point_type<raptor::Point<double> ::NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE::************)(mpl_::assert_::types<raptor::Point<double>, mpl_::na, mpl_::na, mpl_::na>)') to type 'mpl_::assert<false>::type {aka mpl_::assert<false>}'
BOOST_MPL_ASSERT_MSG ^ In file included from
/usr/include/boost/geometry/core/coordinate_type.hpp:21:0,
from /usr/include/boost/geometry/core/access.hpp:24, from Point.hpp:5, from main.cpp:1: /usr/include/boost/geometry/core/point_type.hpp: In instantiation of
'struct boost::geometry::core_dispatch::point_type<void, raptor::Point<double> >':
/usr/include/boost/geometry/core/coordinate_type.hpp:58:62: required from
'struct boost::geometry::core_dispatch::coordinate_type<void, raptor::Point<double> >'
/usr/include/boost/geometry/core/coordinate_type.hpp:92:25: required from
'struct boost::geometry::coordinate_type<raptor::Point<double> >'
/usr/include/boost/geometry/geometries/concepts/point_concept.hpp:90:54:
required from 'class boost::geometry::concept::Point<raptor::Point<double>
'
/usr/include/boost/concept/detail/has_constraints.hpp:32:62: required by
substitution of 'template<class Model> boost::concepts::detail::yes boost::concepts::detail::has_constraints_(Model*, boost::concepts::detail::wrap_constraints<Model, (& Model:: constraints)>*) [with Model = boost::geometry::concept::Point<raptor::Point<double> >]'
/usr/include/boost/concept/detail/has_constraints.hpp:42:5: required from
'const bool boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double>
::value'
/usr/include/boost/concept/detail/has_constraints.hpp:45:31: required
from 'struct boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double>
'
/usr/include/boost/mpl/if.hpp:67:11: required from 'struct
boost::mpl::if_<boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double>
, boost::concepts::constraint<boost::geometry::concept::Point<raptor::Point<double> , boost::concepts::requirement<boost::concepts::failed************ boost::geometry::concept::Point<raptor::Point<double> >::************> >'
/usr/include/boost/concept/detail/general.hpp:50:8: required from 'struct
boost::concepts::requirement_<void (*)(boost::geometry::concept::Point<raptor::Point<double> >)>'
/usr/include/boost/geometry/geometries/ring.hpp:60:5: required from
'class boost::geometry::model::polygon<raptor::Point<double>, true, true, std::vector, std::vector, std::allocator, std::allocator>'
main.cpp:4:42: required from here /usr/include/boost/geometry/core/point_type.hpp:66:17: error: no type named
'type' in 'struct boost::geometry::traits::point_type<raptor::Point<double>
'
>::type type; ^ In file included from
/usr/include/boost/geometry/geometries/polygon.hpp:26:0,
from Point.hpp:10, from main.cpp:1: /usr/include/boost/geometry/geometries/concepts/point_concept.hpp: In
instantiation of 'class boost::geometry::concept::Point<raptor::Point<double> >':
/usr/include/boost/concept/detail/has_constraints.hpp:32:62: required by
substitution of 'template<class Model> boost::concepts::detail::yes boost::concepts::detail::has_constraints_(Model*, boost::concepts::detail::wrap_constraints<Model, (& Model:: constraints)>*) [with Model = boost::geometry::concept::Point<raptor::Point<double> >]'
/usr/include/boost/concept/detail/has_constraints.hpp:42:5: required from
'const bool boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double>
::value'
/usr/include/boost/concept/detail/has_constraints.hpp:45:31: required
from 'struct boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double>
'
/usr/include/boost/mpl/if.hpp:67:11: required from 'struct
boost::mpl::if_<boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double>
, boost::concepts::constraint<boost::geometry::concept::Point<raptor::Point<double> , boost::concepts::requirement<boost::concepts::failed************ boost::geometry::concept::Point<raptor::Point<double> >::************> >'
/usr/include/boost/concept/detail/general.hpp:50:8: required from 'struct
boost::concepts::requirement_<void (*)(boost::geometry::concept::Point<raptor::Point<double> >)>'
/usr/include/boost/geometry/geometries/ring.hpp:60:5: required from
'class boost::geometry::model::polygon<raptor::Point<double>, true, true, std::vector, std::vector, std::allocator, std::allocator>'
main.cpp:4:42: required from here /usr/include/boost/geometry/geometries/concepts/point_concept.hpp:93:10:
error: 'value' is not a member of 'boost::geometry::dimension<raptor::Point<double> >'
enum { ccount = dimension<Geometry>::value }; ^ Where is the problem ? or it's a GCC bug ? Thanks

Hi, 2015-09-19 8:08 GMT+02:00 邓尧 <torshie@gmail.com>:
template<typename T, *int* tDimension = 2>
class Point {
<snip>
template<typename Type, *std::size_t* tDimension>
struct tag<::raptor::Point<Type, tDimension>> {
typedef point_tag type;
};
Different integral types are used for tDimension in Point class and traits specializations, after changing e.g. int to std::size_t in Point class the code compiles.
Regards, Adam

Hi Adam, is there any other way around/through this? I am working with a point geometry with the same issue: the template type for dimensions is 'int' and it would be a lot of hassle to change it. Thanks, cheers. Jeremy On 4 October 2015 at 04:16, Adam Wulkiewicz <adam.wulkiewicz@gmail.com> wrote:
Hi,
2015-09-19 8:08 GMT+02:00 邓尧 <torshie@gmail.com>:
template<typename T, *int* tDimension = 2>
class Point {
<snip>
template<typename Type, *std::size_t* tDimension>
struct tag<::raptor::Point<Type, tDimension>> {
typedef point_tag type;
};
Different integral types are used for tDimension in Point class and traits specializations, after changing e.g. int to std::size_t in Point class the code compiles.
Regards, Adam
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hi Jeremy, Jeremy Murphy wrote:
is there any other way around/through this? I am working with a point geometry with the same issue: the template type for dimensions is 'int' and it would be a lot of hassle to change it.
The type in trait specialization has to be specified correctly. So assuming that you don't want to change the geometry template you should change the specialization, like this: template<typename T, *int*tDimension = 2> class Point {}; // ... template<typename Type, *int*tDimension> struct tag<Point<Type, tDimension>> { typedef point_tag type; }; Adam
On 4 October 2015 at 04:16, Adam Wulkiewicz <adam.wulkiewicz@gmail.com <mailto:adam.wulkiewicz@gmail.com>> wrote:
Hi,
2015-09-19 8:08 GMT+02:00 邓尧 <torshie@gmail.com <mailto:torshie@gmail.com>>:
template<typename T, *int* tDimension = 2>
class Point {
<snip>
template<typename Type, *std::size_t* tDimension>
struct tag<::raptor::Point<Type, tDimension>> {
typedef point_tag type;
};
Different integral types are used for tDimension in Point class and traits specializations, after changing e.g. int to std::size_t in Point class the code compiles.
Regards, Adam
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org <mailto:Boost-users@lists.boost.org> http://lists.boost.org/mailman/listinfo.cgi/boost-users <http://lists.boost.org/mailman/listinfo.cgi/boost-users>

On 15 November 2017 at 22:28, Adam Wulkiewicz <adam.wulkiewicz@gmail.com> wrote:
Hi Jeremy,
Jeremy Murphy wrote:
is there any other way around/through this? I am working with a point geometry with the same issue: the template type for dimensions is 'int' and it would be a lot of hassle to change it.
The type in trait specialization has to be specified correctly. So assuming that you don't want to change the geometry template you should change the specialization, like this:
template<typename T, *int* tDimension = 2> class Point {};
// ...
template<typename Type, *int* tDimension> struct tag<Point<Type, tDimension>> { typedef point_tag type; };
Adam
Thanks, Adam, that worked a treat. Cheers. Jeremy
participants (3)
-
Adam Wulkiewicz
-
Jeremy Murphy
-
邓尧