如何从boost :: geometry :: model :: point继承? [英] How to inherit from boost::geometry::model::point?
问题描述
我想从 rtree .
I'd like to inherit from bg::model::point to extend it with own functionality. The *point*s shall be stored in an rtree.
以下最小示例无法编译我的派生点的用法(提升1.54,gcc 4.7.2):
The following minimal example fails to compile the usage of my derived point (boost 1.54, gcc 4.7.2):
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <iostream>
#include <boost/shared_ptr.hpp>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
namespace boost { namespace geometry { namespace index {
// apparently necessary:
template <typename Box>
struct indexable< boost::shared_ptr<Box> >
{
typedef boost::shared_ptr<Box> V;
typedef Box const& result_type;
result_type operator()(V const& v) const { return *v; }
};
}}} // namespace boost::geometry::index
namespace { // anonymous namespace
// myPoint
template<typename CoordinateType, std::size_t DimensionCount, typename CoordinateSystem>
class myPoint : public bg::model::point<CoordinateType, DimensionCount, CoordinateSystem>{
public:
void sayHello(void);
};
template<typename CoordinateType, std::size_t DimensionCount, typename CoordinateSystem>
void myPoint< CoordinateType, DimensionCount, CoordinateSystem >::sayHello() {
std::cout<<"Hello!"<<std::endl;
}
} // end anonymous namespace
int main(void)
{
typedef bg::model::point<float, 2, bg::cs::cartesian> point; // boost point version
typedef myPoint<float, 2, bg::cs::cartesian> mypoint; // custom point version
// create the rtree using default constructor
bgi::rtree< boost::shared_ptr<point>, bgi::rstar<16, 4> > rtree; // that works
bgi::rtree< boost::shared_ptr<mypoint>, bgi::rstar<16, 4> > myrtree; // that doesn't works
return 0;
}
我如何从bg :: model :: point派生?还是有更好的方法而不是继承?
how can i derive from bg::model::point? or, instead of inheriting, is there a better approach?
谢谢!
推荐答案
Boost.Geometry要求您的Point类型适应此处描述的Point Concept:
Boost.Geometry requires that your Point type is adapted to the Point Concept described here:
您的派生类型myPoint也必须进行修改,因为它是与基本类型model :: pointer<>不同的类型.这样做的原因是,该库允许修改旧式类并将其用作几何图形,而无需进行修改.
Your derived type myPoint must also be adapted because it's a different type than your base type, model::pointer<>. The reason for this is that the library allows to adapt legacy classes and use them as Geometries without the need for modification.
要适应它,您必须使用注册宏之一或自己专门化所有必需的特征.除了评论中提到的示例外,还请参见:
To adapt it you must either use one of the registration macros or specialize all required traits by yourself. Besides the exmaple mentioned in the comment, see those:
http://www. boost.org/doc/libs/1_54_0/libs/geometry/doc/html/geometry/examples.html
在第二种方法中,通过对所有必需特征进行手动专业化来适应Point类型,这是最灵活的方法.在您的情况下,它看起来像这样:
In the second one the Point type is adapted by manual specialization of all required traits, which is the most flexible approach. In your case this would look like this:
namespace boost { namespace geometry { namespace traits {
template <typename C, std::size_t D, typename S>
struct tag< myPoint<C, D, S> >
{
typedef point_tag type;
};
template <typename C, std::size_t D, typename S>
struct coordinate_type< myPoint<C, D, S> >
{
typedef C type;
};
template <typename C, std::size_t D, typename S>
struct coordinate_system< myPoint<C, D, S> >
{
typedef S type;
};
template <typename C, std::size_t D, typename S>
struct dimension< myPoint<C, D, S> >
{
static const std::size_t value = D;
};
template <typename C, std::size_t D, typename S, std::size_t I>
struct access<myPoint<C, D, S>, I>
{
static inline C get(myPoint<C, D, S> const& p)
{
return p.template get<I>();
}
static inline void set(myPoint<C, D, S> & p, C const& v)
{
p.template set<I>(v);
}
};
}}}
只需将其粘贴在Point定义之后即可.
Just paste it after your Point definition and you're done.
这篇关于如何从boost :: geometry :: model :: point继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!