运算符在全局和元素函数中重载

时间:2017-04-13 15:11:44

标签: c++ operator-overloading

我是cC ++的新手。我希望代码片段能够很好地解释我想要实现的目标。我想要一个全局和一个元素函数来重载<运营商。在元素函数中,返回类型是bool,在全局函数中它是相应的类型。这段代码可以实现吗? (现在不工作?)

     class Foo{     
     //...
     //element function:
     bool operator<(const Foo& otherFoo){//implementation}
     }
     //global function:
     Foo& operator<(const Foo& foo1, const Foo& f2)
     {
         if (f1.operator<(f2))
            return f1;
         else;
      return f2;
      }

1 个答案:

答案 0 :(得分:0)

  

这段代码可以实现吗?

是。但你真的,真的,真的应该这样做! operator<有一个非常简洁的含义:左手侧&#34;较少&#34; (对于某些定义&#34; less&#34;)而不是右手?

返回实际上&#34; less&#34;也是一个合理的功能,但应该相应地命名!称之为lesser_of或类似的东西。

  

现在不能正常工作?

您的问题中未包含任何有用的错误说明,但我非常怀疑此处的问题是const正确性。您已接受对const限定Foo的引用,并尝试将其成员函数operator<称为 const。简单的修复:向成员函数添加const

// member function:                 vvvvv
bool operator<(const Foo& otherFoo) const {
  // implementation                 ^^^^^
}

使用模板可以为具有相应成员函数的所有类型实现假定的free(=非成员)函数(应该使用合理的名称调用,我选择lesser_of):

template<typename L, typename R>
typename std::common_type<L,R>::type lesser_of(L&& left, R&& right) {
  using std::forward;
  // Could also use operator<(forward<L>(left), forward<R>(right)), but
  // this breaks when there's both a member function and a free
  // function available.
  if (left.operator<(forward<R>(right))) {
    return forward<L>(left);
  } else {
    return forward<R>(right);
  }
}

请注意,我不知道转发是否有意义,也不确定这是否会导致悬挂引用。

更进一步,我会考虑一种用法&#34;只是好的&#34;如果你真的坚持要回来&#34;更多&#34;而不是来自bool的{​​{1}}:在Common Lisp中,这称为"generalized boolean",基本上意味着除了特殊operator<值之外的任何内容都被视为be&#34; truthy&#34;。你可以&#34; port&#34;那就是C ++并使用std::optional(C ++ 17!)来传达这个含义:

nil

这将返回包含在template<typename L, typename R> std::experimental::optional<L> operator<(L&& left, R&& right) { if (left.operator<(std::forward<R>(right))) { return std::forward<L>(left); } else { return std::experimental::nullopt_t{}; } } 中的左操作数,如果它确实是&#34; less&#34;比右边。可以在例如结果中检查结果。一个std::optional(或类似的&#34;特殊上下文&#34;),因为它有a (explicit) conversion member function to bool。因此,返回if代替std::optional不会破坏仅在可以应用contextual conversions的情况下使用比较的代码。可以通过解除引用或value member function来访问返回的值。

当然,这不允许bool之类的代码,但您可以使用Foo c = a < b;