c++ - 如何让 set::find() 为自定义类对象工作?

标签 c++ stl set

我对使用 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是类对象并且( ifc 是类成员)。

现在我想为 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::tiestd::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/

相关文章:

c++ - 分形编程 - 有什么方法可以优化此代码以进行实时渲染?

java - 我可以创建集合数组吗?

c++ - 位掩码 : Set different states of an object via set method

xcode - 包括 <sstring> header - 找不到文件?

c++ - vector map - 怎么做

c++ - C++中的动态二维数组,需要在每一行和整个数组中乘以偶数

c++ - send() 函数中的错误代码 88(Socket 编程)

java - SortedSet、数组、可序列化的序列化问题

C++ Lambda 函数闭包 - 内存问题

c++ - crt1.o函数_start中未定义对 'main'错误的引用