我是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;
}
答案 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;
。