如何使用 std::set 作为具有显式比较器成员函数的数据成员?

use*_*866 6 c++ comparator stdset c++17

我正在使用 C++17。

std::set是一个模板类型:

template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set;
Run Code Online (Sandbox Code Playgroud)

可以将 astd::set作为数据成员。例如:

#include <set>

class Foo
{
    std::set<size_t> someSet_;
};
Run Code Online (Sandbox Code Playgroud)

还可以明确指定比较函数。例如:

#include <set>

auto compare = [](size_t index1, size_t index2) {
    return index1 < index2;
};

class Foo
{
public:
    Foo() : someSet_(compare)
    {
    }

private:
    std::set<size_t, decltype(compare)> someSet_;
};
Run Code Online (Sandbox Code Playgroud)

现在,假设比较函数是成员函数。例如:

#include <set>
#include <vector>

class Foo
{
public:
    Foo() : someSet_(compare) // does not compile
    {
    }

private:
    bool compare(size_t index1, size_t index2) const
    {
        return someVector_[index1] < someVector_[index2];
    }

    std::vector<int> someVector_;
    std::set<size_t, decltype(compare)> someSet_; // does not compile
};
Run Code Online (Sandbox Code Playgroud)

正如所评论的,最后的代码无法编译。

如何someSet_声明并初始化以使用Foo::compare()

skl*_*ott 10

如果您查看编译器生成的错误,您会发现这compare不可能是非静态函数。所以,通常你做静态函数。但在您的情况下,您需要访问成员变量,在这种情况下,最好创建辅助比较器对象。例如,像这样:

#include <set>
#include <vector>

class Foo
{
public:
    Foo()
    {
    }

private:
    struct comparator {
        comparator(const Foo& foo) : foo_(foo) {}
        bool operator()(size_t index1, size_t index2) const
        {
            return foo_.someVector_[index1] < foo_.someVector_[index2];
        }
    private:
        const Foo& foo_;
    };

    std::vector<int> someVector_;
    comparator comp_{*this};
    std::set<size_t, comparator> someSet_{comp_};
};
Run Code Online (Sandbox Code Playgroud)

PS:但在这种情况下,您需要定义或删除复制/移动构造函数和赋值运算符,因为默认情况下会错误地复制此类比较器。

  • `朋友比较器;`是多余的。会员类别已经可以访问。 (2认同)