无用知识研究?对泛型库(如boost)扩展的思路,带一个对stl里std::common_type进行特化的例子

已经在工程中使用特化来扩展boost的rtree,用于处理自定义数据结构。

boost里有rtree这个数据结构,主要用于空间检索。

它已经提供了std::pair(如下),也

/*!
\brief The function object extracting Indexable from Value.

This specialization translates from std::pair<Indexable, T2>.

\tparam Indexable       The Indexable type.
\tparam Second          The second type.
*/
template <typename Indexable, typename Second>
struct indexable<std::pair<Indexable, Second>, false>
{
    typedef std::pair<Indexable, Second> value_type;

    BOOST_GEOMETRY_STATIC_ASSERT(
        (detail::is_indexable<Indexable>::value),
        "The first type of std::pair has to be an Indexable.",
        Indexable);

    /*! \brief The type of result returned by function object. */
    typedef Indexable const& result_type;

    /*!
    \brief Return indexable extracted from the value.
    
    \param v The value.
    \return The indexable.
    */
    inline result_type operator()(value_type const& v) const
    {
        return v.first;
    }

    /*!
    \brief Return indexable extracted from compatible type different than value_type.

    \param v The value.
    \return The indexable.
    */
    template <typename I, typename S>
    inline result_type operator()(std::pair<I, S> const& v) const
    {
        BOOST_GEOMETRY_STATIC_ASSERT(
            (is_referencable<I, result_type>::value),
            "Unexpected type.",
            std::pair<I, S>);
        return v.first;
    }

    /*!
    \brief Prevent reference to temporary for types convertible to Value.
    */
    template <typename V>
    inline result_type operator()(V const& v) const
    {
        return indexable_prevent_any_type<Indexable>(v);
    }
};

利用特化,可以检索自己的自定义数据,如下面的Point2CisdiCurveList,里面的key用于检索,剩下的两个成员变量作为携带的数据。

/*--------------------------------------------------------------------------------------**//**
* 通过空间点,来查询空间曲线                                            
*                                                            Created by Simon.Zou on 7/2021
+---------------+---------------+---------------+---------------+---------------+-----------*/
struct Point2CisdiCurveList 
{
   // typedef PointFindCurve::BDPoint BDPoint; //双精度的点
    using BDPoint = boost::geometry::model::point<double, 3, boost::geometry::cs::cartesian> ; //双精度的点
    using BoostDBox = boost::geometry::model::box<BDPoint> ; //立方体

    using Value = std::pair<BoostDBox, CurveVectorPtr> ;
    using MyRTree = boost::geometry::index::rtree<PointFindCurve::Value, boost::geometry::index::quadratic<16>> ; //双精度的点

    //typedef boost::geometry::model::point<double, 3, boost::geometry::cs::cartesian> BoostPoint3d; //双精度的点
    BDPoint key;
    std::list<CurveVectorPtr> cisdiCurve2DLst;
    std::list<CurveVectorPtr> cisdiCurve3DLst;
};

/*--------------------------------------------------------------------------------------**//**
*  特化
* Point2CisdiCurveList里定义了key和对应的数据                                           
*                                                            Created by Simon.Zou on 9/2021
+---------------+---------------+---------------+---------------+---------------+-----------*/
template <>
struct boost::geometry::index::indexable<Point2CisdiCurveList>
{
    typedef Point2CisdiCurveList::BDPoint result_type; //这个不能缺少
    //boostPoint2d operator()(const CityRef& c) const { return c.location; }
    const Point2CisdiCurveList::BDPoint& operator()(const Point2CisdiCurveList& c) const { 
return c.key; 
}
};


/*--------------------------------------------------------------------------------------**//**
* 点找到线的list                                            
*                                                            Created by Simon.Zou on 8/2021
+---------------+---------------+---------------+---------------+---------------+-----------*/
struct PointFindCurveList
{
    typedef Point2CisdiCurveList::BDPoint BDPoint; //双精度的点
    typedef boost::geometry::index::rtree<Point2CisdiCurveList, boost::geometry::index::linear<16> > MyRTree;

//     static BoostDBox CreateBoostDBox(DPoint3dR pt,  //IN
//         double dDis = 1 * UOR_PER_MM //IN
//     ){return PointFindCurve::CreateBoostDBox(pt, dDis);}

    static bool Add1Point1Curve(PointFindCurveList::MyRTree& rtree,  //IN
        DPoint3dR pt, //IN
        CurveVectorPtr curve2d, //IN
        CurveVectorPtr curve3d, //IN
        //bool bAllow3dPointDuplicate = false, //IN 是否允许通过空间点查到多个数据
        double dDis = 1 * UOR_PER_MM //IN
    )
{
    PointFindCurve::BoostDBox b = PointFindCurve::CreateBoostDBox(pt, dDis);
    
    /*--------------------------------------------------------------------------------------**//**
    * 如果能找到,则更新:
    *      删除唯一记录,然后插入记录                             Commented by Simon.Zou on 7/2021
    +---------------+---------------+---------------+---------------+---------------+-----------*/
    bool bFind = false;
    for (PointFindCurveList::MyRTree::const_query_iterator
        it = rtree.qbegin(boost::geometry::index::intersects(b));
        it != rtree.qend();
        ++it)
    {
        bFind = true;

        Point2CisdiCurveList& lst = const_cast<Point2CisdiCurveList&>(*it);
        lst.cisdiCurve2DLst.push_back(curve2d);
        lst.cisdiCurve3DLst.push_back(curve3d);
    }

    if (!bFind)
    {
        std::list<CurveVectorPtr> cisdiCurveLst;
        Point2CisdiCurveList o;
        o.key.set<0>(pt.x);
        o.key.set<1>(pt.y);
        o.key.set<2>(pt.z);
        o.cisdiCurve2DLst.push_back(curve2d);
        o.cisdiCurve3DLst.push_back(curve3d);
        rtree.insert(o);//r树插入外包围矩形 i为索引
        return true;
    }

    return true;
}

    static bool FindByPoint(std::list<Point2CisdiCurveList>& result_s, //OUT
        PointFindCurveList::MyRTree& rtree, //IN
        DPoint3dR pt, //IN
        double dDis = 1 * UOR_PER_MM //IN
    )
{
    PointFindCurve::BoostDBox b = PointFindCurve::CreateBoostDBox(pt, dDis);
    //std::vector<Value> result_s;
    int size = (int)rtree.query(boost::geometry::index::intersects(b), std::back_inserter(result_s));
    if (size == 0)
        return false;
    //if (result_s.size() == 0)
    //    m_rtree.query(boost::geometry::index::nearest(BDPoint(ptRes.x, ptRes.y, ptRes.z), 2), std::back_inserter(result_s));

    return !result_s.empty();
}


};
下面代码运行结果是:0
说明“共同类型”(在被特化后)是Ex0


struct Ex0 {
  int a = 0;
};
struct Ex1 {
  int a = 1;
};

//没错,这个std就是stl的那个std
//就是为了对stl的common_type进行特化。
//否则的话,光用stl的肯定是编译不过。因为Ex0和Ex1不是一个类型,没法转换
namespace std {
template <> 
struct common_type<Ex0, Ex1> 
{ 
    using type = Ex0; //说明:decltype(true? Ex0:Ex1)的结果就是Ex0
};
} 
void testOwner() {
  using type = std::common_type_t<Ex0, Ex1>;
  type m;
  std::cout << "cur class value:" << m.a << std::endl;
}
————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.youkuaiyun.com/fpcc/article/details/136000816
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值