You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将带显式成员函数比较器的std::set作为类数据成员?

使用成员函数作为std::set比较器的C++17实现方案

问题背景

我使用的是C++17标准,std::set是一个模板类型,定义如下:

template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set;

可以直接将std::set作为类的数据成员:

#include <set>

class Foo
{
    std::set<size_t> someSet_;
};

也可以显式指定lambda作为比较函数:

#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_;
};

但当尝试用类的非静态成员函数作为比较器时,以下代码无法编译:

#include <set>
#include <vector>

class Foo
{
public:
    Foo() : someSet_(compare) // 无法编译
    {
    }

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_; // 无法编译
};

问题:如何正确声明并初始化someSet_,使其能够使用Foo::compare()成员函数作为比较器?

解决方案

方法1:用捕获this的lambda作为比较器

直接在构造函数中定义捕获当前对象指针的lambda,作为std::set的比较器,同时注意成员变量的声明顺序(someVector_要在someSet_之前):

#include <set>
#include <vector>

class Foo
{
public:
    Foo() : someSet_(
        [this](size_t index1, size_t index2) {
            return compare(index1, index2);
        }
    )
    {
    }

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

    std::vector<int> someVector_;
    std::set<size_t, decltype([this](size_t, size_t){return false;})> someSet_;
};

或者更简洁地直接在lambda内实现逻辑,避免额外成员函数:

#include <set>
#include <vector>

class Foo
{
public:
    Foo() : someSet_(
        [this](size_t index1, size_t index2) {
            return someVector_[index1] < someVector_[index2];
        }
    )
    {
    }

private:
    std::vector<int> someVector_;
    std::set<size_t, decltype([this](size_t, size_t){return false;})> someSet_;
};

方法2:自定义比较器类,持有对象引用

定义一个嵌套的比较器类,它持有Foo的const引用,这样就能访问Foo的成员:

#include <set>
#include <vector>

class Foo
{
public:
    Foo() : someSet_(Comparator{*this})
    {
    }

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

    std::vector<int> someVector_;
    std::set<size_t, Comparator> someSet_;
};

注意事项

  • 非静态成员函数需要依赖对象实例才能调用,因此不能直接作为std::set的比较器类型(decltype(compare)得到的是成员函数指针类型,而std::set需要的是可独立调用的对象类型)。
  • 成员变量声明顺序很重要:someVector_必须在someSet_之前,确保构造someSet_时someVector_已经完成初始化。

内容的提问来源于stack exchange,提问作者user1387866

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 15:30:51