I want to create a map of indices to vertices:
using IndicesToVertices = std::map<Eigen::Vector3f, uint32_t>;
But operator< is not defined for Eigen::Vector3f. I don't want to mess with the class itself, so I cannot declare a friend operator< for it, which seems recommended for custom "owned" types.
I have tried to derive a type from it, which only added the operator< as its member, but encountered problems, when the derived type needed to interact with other Eigen classes (e.g. Eigen::AngleAxisf() - when multiplying it by Eigen::Vector3f and adding the result to Eigen::Vector3f). Eigen::Vector3f is a template specialization and these other types as well. There seem to be some complex things happening, which prevent easy derivation from these types, with hope that it will work with other - not derived types.
Then I have looked at other possibilities, like specializing a template for 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());
}
};
}
This is not recommended "here and there" (e.g Specialization of 'template<class _Tp> struct std::less' in different namespace) and - more importantly for me - doesn't compile, throwing strange errors, which I don't understand, like: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-errors-2/compiler-error-c3848?view=msvc-160
I may be left with declaring IndicesToVertices with custom comparator function, which specializes std::map, . Is this the best way? If so, how to do it properly?
It would be nice if the answer included reasoning about the possible issues due to to fact, that it is not safe to compare floats, which happens under the hood in std::lexicographical_compare or other implementations. Then, when trying to remap indices for a subset of vertices form the map - is it possible, that "bad things" can happen?