std::set 比较函数的自定义参数 [英] Custom arguments to std::set comparison function

查看:30
本文介绍了std::set 比较函数的自定义参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I know how to pass a regular comparison class or function to set::set<>.

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

I am writing some test code and I want to emulate some C libraries using STL's std::set and I want to be able to pass a C callback to the comparison object so a different comparison takes place.

我有以下理论代码:

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 对象,将它传递给cmp",然后使用该特定集合的初始化比较对象.

But I cannot, somehow, instantiate a MyComparison object, pass it "cmp" and then use that initialize comparison object with that specific set.

有没有办法做到这一点?

Is there a way to achieve that?

推荐答案

您断言您不能将 MyComparison 实例传递给 std::set 以使其使用它是错误的.有一个 std::set 的构造函数,只需要(在 C++11 中):

Your assertion that you can't pass a MyComparison instance to std::set for it to use it is wrong. There is a constructor for std::set expecting just that (in C++11):

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

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

So your MyComparison can be passed as first argument.

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

如果您没有 C++11 或更高版本可用,则此构造函数重载不存在,您需要使用另一个:

If you don't have C++11 or newer available, then this constructor overload is non-existing and you need to use another one:

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

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

This one however expects an interator range in the first two arguments. Since we don't actually want to construct from a range, they need to be dummies. You could do someting like:

std::vector<int> dummy;
std::set<MyClass, MyComparison> m1(dummy.begin(), dummy.end(), mycomp);

dummy 之后将不再使用.除了实现一个虚拟迭代器类之外,我不确定是否有更好的解决方案.

dummy will not be used afterwards. I am not sure whether there is a nicer solution besides implementing a dummy iterator class.

参见 http://en.cppreference.com/w/cpp/container/set/set 完整参考 std::set 的构造函数.

See http://en.cppreference.com/w/cpp/container/set/set for full reference on constructors of std::set.

这篇关于std::set 比较函数的自定义参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆