微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何为 Eigen::Vector3f 定义小于 (<) 运算符或 std::less 结构?

如何解决如何为 Eigen::Vector3f 定义小于 (<) 运算符或 std::less 结构?

我想创建一个索引到顶点的映射:

using IndicesToVertices = std::map<Eigen::Vector3f,uint32_t>;

但是没有为 Eigen::Vector3f 定义 operator

我试图从中派生一个类型,它只添加了 operator

然后我研究了其他可能性,比如为 std::less (Using std::map with Eigen 3) 专门设计一个模板

namespace std {
template<>
    struct std::less<Vec3>
    {
        bool operator() (const Vec3& a,const Vec3& b) const
        {
           return std::lexicographical_compare(a.begin(),a.end(),b.begin(),b.end());
        }
    };
}

不建议“到处”(例如Specialization of 'template<class _Tp> struct std::less' in different namespace)并且 - 对我来说更重要的是 - 不编译,抛出奇怪的错误,我不明白,例如:https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-2/compiler-error-c3848?view=msvc-160

我可能需要使用自定义比较器函数声明 IndicesToVertices,该函数专门用于 std::map,。这是最好的方法吗?如果是这样,如何正确操作?

如果答案包括对可能问题的推理,因为比较浮点数是不安全的,这会很好,这在 std::lexicographical_compare 或其他实现中发生。然后,当尝试重新映射来自地图的顶点子集的索引时 - 是否可能发生“坏事”?

解决方法

使用浮点值(或聚合)作为映射的键通常是一个非常糟糕的主意。

这是一个基本的设计问题。我的意思是,如果有 NaN,一切都会爆炸。一个浮点值的两个看似相同的派生可以比较不相等。

但编写比较运算符并不难。

struct LexographicLess {
  template<class T>
  bool operator()(T const& lhs,T const& rhs) const {
    return std::lexographical_compare(lhs.begin(),lhs.end(),rhs.begin(),rhs.end());
  }
};

然后简单地做:

std::map<Eigen::Vector3f,uint32_t,LexographicLess>;

我们可以解决“NaN”问题:

template<class L=std::less<>>
struct LexographicLess {
  template<class T>
  bool operator()(T const& lhs,rhs.end(),L{});
  }
};

这让我们可以传入一个“sub-less”,我们可以针对 NaN 问题进行强化。

正确执行此操作将取决于您的问题框架。您的空间是否必须支持从集成电路上的门布局一直到数光年以外的位置?如果没有,您可以重新考虑使用浮点值。

其次,使用像 std::map 这样的一维有序映射的空间映射通常是一个坏主意。了解四叉树和八叉树是什么,它们在 2 维或 3 维中组织事物,以便在数据结构中附近的事物就在附近。

“这个函数在这个坐标附近的值是什么”这个问题比“为这个精确点存储的值是多少”更明智,这几乎是无稽之谈在连续体上,并且在浮点连续体近似中效果不佳。

但这远远超出了范围。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。