英文:
boost r-tree error: The first type of std::pair has to be an Indexable. How do I fix this?
问题
I'm using boost::geometry::index::rtree
with the point type given by Eigen::Vector
. To do this, I'm declaring:
namespace boost
{
namespace geometry
{
namespace traits
{
template<typename T, std::size_t D> struct tag<Eigen::Vector<T, D>> { using type = point_tag; };
template<typename T, std::size_t D> struct dimension<Eigen::Vector<T, D>> : boost::mpl::int_<D> {};
template<typename T, std::size_t D> struct coordinate_type<Eigen::Vector<T, D>> { using type = T; };
template<typename T, std::size_t D> struct coordinate_system<Eigen::Vector<T, D>> { using type = boost::geometry::cs::cartesian; };
template<typename T, std::size_t D, std::size_t Index>
struct access<Eigen::Vector<T, D>, Index>
{
static_assert(Index < D, "out of range");
using Point = Eigen::Vector<T, D>;
using CoordinateType = typename coordinate_type<Point>::type;
static inline CoordinateType get(Point const& p) { return p[Index]; }
static inline void set(Point& p, CoordinateType const& value) { p[Index] = value; }
};
} // namespace traits
} // namespace geometry
} // namespace boost
Then I declare:
```cpp
template<class PointType>
using rtree = boost::geometry::index::rtree<PointType, boost::geometry::index::rstar<16>>;
rtree<std::pair<Eigen::Vector<double, 2>, std::size_t>> foo;
While this perfectly compiles using MSVC, I'm receiving the error:
error: static assertion failed: The first type of std::pair has to be an Indexable. 24 |
when I compile it under Linux/GCC. What's going wrong here and how do I fix it?
英文:
I'm using boost::geometry::index::rtree
with the point type given by Eigen::Vector
. To do this, I'm declaring
namespace boost
{
namespace geometry
{
namespace traits
{
template<typename T, std::size_t D> struct tag<Eigen::Vector<T, D>> { using type = point_tag; };
template<typename T, std::size_t D> struct dimension<Eigen::Vector<T, D>> : boost::mpl::int_<D> {};
template<typename T, std::size_t D> struct coordinate_type<Eigen::Vector<T, D>> { using type = T; };
template<typename T, std::size_t D> struct coordinate_system<Eigen::Vector<T, D>> { using type = boost::geometry::cs::cartesian; };
template<typename T, std::size_t D, std::size_t Index>
struct access<Eigen::Vector<T, D>, Index>
{
static_assert(Index < D, "out of range");
using Point = Eigen::Vector<T, D>;
using CoordinateType = typename coordinate_type<Point>::type;
static inline CoordinateType get(Point const& p) { return p[Index]; }
static inline void set(Point& p, CoordinateType const& value) { p[Index] = value; }
};
} // namespace traits
} // namespace geometry
} // namespace boost
Then I declare
template<class PointType>
using rtree = boost::geometry::index::rtree<PointType, boost::geometry::index::rstar<16>>;
and rtree<std::pair<Eigen::Vector<double, 2>, std::size_t>> foo;
. While this perfectly compiles using MSVC, I'm receiving the error
> error: static assertion failed: The first type of std::pair has to be
> an Indexable. 24 |
> static_assert(boost::geometry::detail::static_assert_check<(CHECK),
> VA_ARGS>::value, MESSAGE)
when I compile it under Linux/GCC. What's going wrong here and how do I fix it?
答案1
得分: 2
以下是您提供的内容的中文翻译:
一些情况下,GCC不会匹配部分模板特化,除非您将std::size_t D
模板参数更改为int
。
这可能与对缩小限制的内部解释有关,但我觉得这可能是某个版本的GCC中的一个错误(某些版本?)。 Clang 15像您报告的MSVC一样接受它。
更改后,在我的GCC版本上也修复了它:
#include <Eigen/StdVector>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/adapted/std_array.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/index/rtree.hpp>
namespace bgi = boost::geometry::index;
namespace boost::geometry::traits {
template <typename T, int D> struct tag<Eigen::Vector<T, D>> {
using type = point_tag;
};
template <typename T, int D> struct dimension<Eigen::Vector<T, D>> : boost::mpl::int_<D> {};
template <typename T, int D> struct coordinate_type<Eigen::Vector<T, D>> {
using type = T;
};
template <typename T, int D> struct coordinate_system<Eigen::Vector<T, D>> {
using type = boost::geometry::cs::cartesian;
};
template <typename T, int D, std::size_t Index> struct access<Eigen::Vector<T, D>, Index> {
static_assert(Index < D, "超出范围");
using Point = Eigen::Vector<T, D>;
using CoordinateType = typename coordinate_type<Point>::type;
static inline CoordinateType get(Point const& p) { return p[Index]; }
static inline void set(Point& p, CoordinateType const& value) { p[Index] = value; }
};
} // namespace boost::geometry::traits
int main() {//
using Point = Eigen::Vector<double, 2>;
bgi::rtree<std::pair<Point, std::size_t>, bgi::rstar<16>> foo;
}
希望这对您有所帮助。如果您需要进一步的翻译或帮助,请告诉我。
英文:
Somehow, GCC doesn't match the partial template specialization unless you make std::size_t D
template parameter int
.
This probably has to do with an internal interpretation of narrowing restrictions, but I feel it might have been a bug (in some version(s) of GCC?). Clang 15 accepts it just like you report MSVC did.
Changing that fixes it on my GCC versions as well:
#include <Eigen/StdVector>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/adapted/std_array.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/index/rtree.hpp>
namespace bgi = boost::geometry::index;
namespace boost::geometry::traits {
template <typename T, int D> struct tag<Eigen::Vector<T, D>> {
using type = point_tag;
};
template <typename T, int D> struct dimension<Eigen::Vector<T, D>> : boost::mpl::int_<D> {};
template <typename T, int D> struct coordinate_type<Eigen::Vector<T, D>> {
using type = T;
};
template <typename T, int D> struct coordinate_system<Eigen::Vector<T, D>> {
using type = boost::geometry::cs::cartesian;
};
template <typename T, int D, std::size_t Index> struct access<Eigen::Vector<T, D>, Index> {
static_assert(Index < D, "out of range");
using Point = Eigen::Vector<T, D>;
using CoordinateType = typename coordinate_type<Point>::type;
static inline CoordinateType get(Point const& p) { return p[Index]; }
static inline void set(Point& p, CoordinateType const& value) { p[Index] = value; }
};
} // namespace boost::geometry::traits
int main() {//
using Point = Eigen::Vector<double, 2>;
bgi::rtree<std::pair<Point, std::size_t>, bgi::rstar<16>> foo;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论