Why does std::less<Eigen::VectorXd> fail to compile?

这一生的挚爱 提交于 2019-12-05 04:15:19

Here's the thing. Your T doesn't recreate the situation reliably. You omitted the namespace, which is very important. A closer example to the case with Eigen would be this:

namespace Foo {
  struct T
  {
    int x;
  };
}

bool operator<(const Foo::T& t1, const Foo::T& t2)
{
    return t1.x < t2.x;
}

And it will produce the exact same error. That is because a template will only consider overloads of this operator that are found at the point of the template definition (and not instantiation), or by argument dependent lookup on the types of the operands.

And for argument dependent lookup to work, the operator and the type must be defined in the same namespace, which yours clearly isn't.

So what happens is this, you include functional. That defines the template std::less in your translation unit. At that time, there is no operator< for Eigen::VectorXd in sight. So the template definition will not take it into consideration when it's defined later.

When you instantiate the template, it attempts to look for a suitable overload among those it was made aware off, and then by ADL. Since your operator< is not inside the Eigen namespace, it isn't found by ADL either.

So long story short, it's impractical to overload operators for library types. What you should do, is to define a custom comparator type:

struct VectorXdCompare {
  bool operator()(const VectorXd& v1, const VectorXd& v2) {
     return (v1.array() <= v2.array()).all() and (v1 != v2);
  }
};

And pass that VectorXdCompare as the type, whenever the standard library needs it.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!