std::set 比较函数的自定义参数 [英] Custom arguments to std::set comparison function
问题描述
我知道如何将常规比较类或函数传递给 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屋!