问题
I know how to pass a regular comparison class or function to set::set<>.
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.
I have the following theoretical code:
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;
};
Now notice how I can do:
std::set<MyClass, MyComparison> m1;
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?
回答1:
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() );
So your MyComparison
can be passed as first argument.
std::set<MyClass, MyComparison> m1(mycmp);
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() );
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
will not be used afterwards. I am not sure whether there is a nicer solution besides implementing a dummy iterator class.
See http://en.cppreference.com/w/cpp/container/set/set for full reference on constructors of std::set
.
来源:https://stackoverflow.com/questions/39884827/custom-arguments-to-stdset-comparison-function