boost r-tree error: The first type of std::pair has to be an Indexable. How do I fix this?

huangapple go评论88阅读模式
英文:

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:

  1. namespace boost
  2. {
  3. namespace geometry
  4. {
  5. namespace traits
  6. {
  7. template<typename T, std::size_t D> struct tag<Eigen::Vector<T, D>> { using type = point_tag; };
  8. template<typename T, std::size_t D> struct dimension<Eigen::Vector<T, D>> : boost::mpl::int_<D> {};
  9. template<typename T, std::size_t D> struct coordinate_type<Eigen::Vector<T, D>> { using type = T; };
  10. template<typename T, std::size_t D> struct coordinate_system<Eigen::Vector<T, D>> { using type = boost::geometry::cs::cartesian; };
  11. template<typename T, std::size_t D, std::size_t Index>
  12. struct access<Eigen::Vector<T, D>, Index>
  13. {
  14. static_assert(Index < D, "out of range");
  15. using Point = Eigen::Vector<T, D>;
  16. using CoordinateType = typename coordinate_type<Point>::type;
  17. static inline CoordinateType get(Point const& p) { return p[Index]; }
  18. static inline void set(Point& p, CoordinateType const& value) { p[Index] = value; }
  19. };
  20. } // namespace traits
  21. } // namespace geometry
  22. } // namespace boost
  23. Then I declare:
  24. ```cpp
  25. template<class PointType>
  26. using rtree = boost::geometry::index::rtree<PointType, boost::geometry::index::rstar<16>>;
  27. 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

  1. namespace boost
  2. {
  3. namespace geometry
  4. {
  5. namespace traits
  6. {
  7. template&lt;typename T, std::size_t D&gt; struct tag&lt;Eigen::Vector&lt;T, D&gt;&gt; { using type = point_tag; };
  8. template&lt;typename T, std::size_t D&gt; struct dimension&lt;Eigen::Vector&lt;T, D&gt;&gt; : boost::mpl::int_&lt;D&gt; {};
  9. template&lt;typename T, std::size_t D&gt; struct coordinate_type&lt;Eigen::Vector&lt;T, D&gt;&gt; { using type = T; };
  10. template&lt;typename T, std::size_t D&gt; struct coordinate_system&lt;Eigen::Vector&lt;T, D&gt;&gt; { using type = boost::geometry::cs::cartesian; };
  11. template&lt;typename T, std::size_t D, std::size_t Index&gt;
  12. struct access&lt;Eigen::Vector&lt;T, D&gt;, Index&gt;
  13. {
  14. static_assert(Index &lt; D, &quot;out of range&quot;);
  15. using Point = Eigen::Vector&lt;T, D&gt;;
  16. using CoordinateType = typename coordinate_type&lt;Point&gt;::type;
  17. static inline CoordinateType get(Point const&amp; p) { return p[Index]; }
  18. static inline void set(Point&amp; p, CoordinateType const&amp; value) { p[Index] = value; }
  19. };
  20. } // namespace traits
  21. } // namespace geometry
  22. } // namespace boost

Then I declare

  1. template&lt;class PointType&gt;
  2. using rtree = boost::geometry::index::rtree&lt;PointType, boost::geometry::index::rstar&lt;16&gt;&gt;;

and rtree&lt;std::pair&lt;Eigen::Vector&lt;double, 2&gt;, std::size_t&gt;&gt; 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版本上也修复了它:

在Compiler Explorer上查看

  1. #include <Eigen/StdVector>
  2. #include <boost/geometry.hpp>
  3. #include <boost/geometry/geometries/adapted/std_array.hpp>
  4. #include <boost/geometry/geometries/register/point.hpp>
  5. #include <boost/geometry/index/rtree.hpp>
  6. namespace bgi = boost::geometry::index;
  7. namespace boost::geometry::traits {
  8. template <typename T, int D> struct tag<Eigen::Vector<T, D>> {
  9. using type = point_tag;
  10. };
  11. template <typename T, int D> struct dimension<Eigen::Vector<T, D>> : boost::mpl::int_<D> {};
  12. template <typename T, int D> struct coordinate_type<Eigen::Vector<T, D>> {
  13. using type = T;
  14. };
  15. template <typename T, int D> struct coordinate_system<Eigen::Vector<T, D>> {
  16. using type = boost::geometry::cs::cartesian;
  17. };
  18. template <typename T, int D, std::size_t Index> struct access<Eigen::Vector<T, D>, Index> {
  19. static_assert(Index < D, "超出范围");
  20. using Point = Eigen::Vector<T, D>;
  21. using CoordinateType = typename coordinate_type<Point>::type;
  22. static inline CoordinateType get(Point const& p) { return p[Index]; }
  23. static inline void set(Point& p, CoordinateType const& value) { p[Index] = value; }
  24. };
  25. } // namespace boost::geometry::traits
  26. int main() {//
  27. using Point = Eigen::Vector<double, 2>;
  28. bgi::rtree<std::pair<Point, std::size_t>, bgi::rstar<16>> foo;
  29. }

希望这对您有所帮助。如果您需要进一步的翻译或帮助,请告诉我。

英文:

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:

Live On Compiler Explorer

  1. #include &lt;Eigen/StdVector&gt;
  2. #include &lt;boost/geometry.hpp&gt;
  3. #include &lt;boost/geometry/geometries/adapted/std_array.hpp&gt;
  4. #include &lt;boost/geometry/geometries/register/point.hpp&gt;
  5. #include &lt;boost/geometry/index/rtree.hpp&gt;
  6. namespace bgi = boost::geometry::index;
  7. namespace boost::geometry::traits {
  8. template &lt;typename T, int D&gt; struct tag&lt;Eigen::Vector&lt;T, D&gt;&gt; {
  9. using type = point_tag;
  10. };
  11. template &lt;typename T, int D&gt; struct dimension&lt;Eigen::Vector&lt;T, D&gt;&gt; : boost::mpl::int_&lt;D&gt; {};
  12. template &lt;typename T, int D&gt; struct coordinate_type&lt;Eigen::Vector&lt;T, D&gt;&gt; {
  13. using type = T;
  14. };
  15. template &lt;typename T, int D&gt; struct coordinate_system&lt;Eigen::Vector&lt;T, D&gt;&gt; {
  16. using type = boost::geometry::cs::cartesian;
  17. };
  18. template &lt;typename T, int D, std::size_t Index&gt; struct access&lt;Eigen::Vector&lt;T, D&gt;, Index&gt; {
  19. static_assert(Index &lt; D, &quot;out of range&quot;);
  20. using Point = Eigen::Vector&lt;T, D&gt;;
  21. using CoordinateType = typename coordinate_type&lt;Point&gt;::type;
  22. static inline CoordinateType get(Point const&amp; p) { return p[Index]; }
  23. static inline void set(Point&amp; p, CoordinateType const&amp; value) { p[Index] = value; }
  24. };
  25. } // namespace boost::geometry::traits
  26. int main() {//
  27. using Point = Eigen::Vector&lt;double, 2&gt;;
  28. bgi::rtree&lt;std::pair&lt;Point, std::size_t&gt;, bgi::rstar&lt;16&gt;&gt; foo;
  29. }

huangapple
  • 本文由 发表于 2023年5月7日 06:05:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76191373.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定