std :: set比较函数的自定义参数

时间:2016-10-05 22:46:00

标签: c++ parameters stl set runtime

我知道如何将常规比较类或函数传递给set :: set<>。

我正在编写一些测试代码,我想使用STL的std :: set模拟一些C库,我希望能够将C回调传递给比较对象,以便进行不同的比较。 / p>

我有以下理论代码:

struct MyClass
{
    int a;
};

typedef bool (*user_callback_t)(void *, void *);
class MyComparison
{
private:
    user_callback_t cb = nullptr;
public:
    MyComparison(user_callback_t cb): cb(cb) { }
    MyComparison() {}
    bool operator()(const MyClass &a, const MyClass &b) const
    {
        return cb((void *)&a, (void *)&b);
    }
};

int f1()
{
    auto cmp = [](void *a, void *b) -> bool
    {
        return *(int *)a < *(int *)b;
    };

    MyComparison mycmp(cmp);

    std::set<MyClass, MyComparison> m1;

    m1.insert({ 1 });
    m1.insert({ 2 });
    m1.insert({ 3 });

    return 0;
};

现在注意我该怎么做:

   std::set<MyClass, MyComparison> m1;

但我不能以某种方式实例化MyComparison对象,传递它&#34; cmp&#34;然后使用该初始化比较对象与该特定集合。

有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:1)

您断言无法将MyComparison实例传递给std::set以使其使用它是错误的。 std::set有一个构造函数(在C ++ 11中):

explicit set( const Compare& comp = Compare(),
              const Allocator& alloc = Allocator() );

所以你的MyComparison可以作为第一个参数传递。

std::set<MyClass, MyComparison> m1(mycmp);

如果你没有C ++ 11或更新版本,那么这个构造函数重载是不存在的,你需要使用另一个:

template< class InputIt >
set( InputIt first, InputIt last,
     const Compare& comp = Compare(),
     const Allocator& alloc = Allocator() );

然而,这个期望在前两个参数中有一个interator范围。由于我们实际上并不想从一个范围构建,因此它们需要是假人。你可以这样做:

std::vector<int> dummy;
std::set<MyClass, MyComparison> m1(dummy.begin(), dummy.end(), mycomp);
之后不会使用

dummy。除了实现虚拟迭代器类之外,我不确定是否有更好的解决方案。

有关std::set的构造函数的完整参考,请参阅http://en.cppreference.com/w/cpp/container/set/set