我对使用 STL 有点困惑 set::find()
对于一组我自己定义的类对象。
我的类(class)包含两个以上的项目(3/4/5 等),那么我如何重载 less
运营商?
我尝试了 3 个变量,如下所示并且工作正常:
return( (a1.i < a2.i) ||
(!(a1.i > a2.i) && (a1.f < a2.f)) ||
(!(a1.i > a2.i) && !(a1.f > a2.f) && (a1.c < a2.c)));
其中,a1
, 和 a2
是类对象并且( i
、 f
和 c
是类成员)。
现在我想为 n 个成员概括这个,但是我的 find()
并不总是有效。
我一直在查看 STL 的详细文档,试图了解如何 set::find()
已实现,以及为什么它需要更少的 ( <
) 运算符重载。
我引用了 sgi 和 msdn 文档,但我找不到太多关于 set::find()
的实现细节。那里,要么。
我在 set::find()
中做错了什么实现?
最佳答案
您可以使用元组轻松获得成员的字典顺序:
return std::tie(lhs.i, lhs.f, lhs.c) < std::tie(rhs.i, rhs.f, rhs.c);
这要求每个成员都是可比较的类型,例如lhs.i < rhs.i
有道理。
请注意 std::tie
和 std::tuple
仅适用于 C++11,因此对于 C++03,您可以使用例如Boost.Tuple 确实提供了 boost::tie
( boost::tuple
使用与 std::tuple
相同的顺序)。
至于应该去哪里,习惯上把它放在 operator<
中。 (毕竟这就是使用 tie
来轻松订购的原因)。这个运算符(operator)通常是 friend ,所以这看起来像:
class foo {
public:
/* public interface goes here */
// declaration of non-member friend operator
// if it doesn't need to be a friend, this declaration isn't needed
friend
bool operator<(foo const& lhs, foo const& rhs);
private:
T t;
U u;
V v;
};
bool operator<(foo const& lhs, foo const& rhs)
{
// could be boost::tie
return std::tie(lhs.t, lhs.u, lhs.v) < std::tie(rhs.t, rhs.u, rhs.v);
}
如您所见,它不是完全自动执行的 operator<
需要列出 foo
的每个成员(或至少那些对订购很重要的),两次。恐怕没有更好的方法了。
而不是提供 operator<
你可以专攻std::less
对于 foo
但这有点异国情调,不是首选方式。如果排序对于成为 foo
的扩展接口(interface)的一部分仍然没有意义(例如,在没有规范的情况下,可能有不止一种有意义的排序),那么首选的方法是编写一个仿函数:
struct foo_ordering {
bool operator()(foo const& lhs, foo const& rhs) const
{
/* implementation as before, but access control/friendship
has to be planned for just like for operator< */
}
};
然后你会使用例如std::set<foo, foo_ordering>
.
请注意,无论排序采用何种形式(通过 operator<
、std::less<foo>
或仿函数),如果它与 std::set
一起使用或任何其他关联容器(默认情况下,例如 std::set<T>
使用 std::less<T>
,而默认情况下又使用 operator<
)它必须遵循一些严格的标准,即它必须是严格的弱排序。但是,如果用于 foo
的所有成员排序本身具有 SW 排序,那么由此产生的词典顺序也是 SW 排序。
关于c++ - 如何让 set::find() 为自定义类对象工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9789542/