我知道如何将常规比较类或函数传递给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;然后使用该初始化比较对象与该特定集合。
有没有办法实现这个目标?
答案 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。