[英]Passing external data to std::set Compare functor
This is a contrived example, I know it doesn't make sense in this context.这是一个人为的例子,我知道在这种情况下它没有意义。 In my real case, v
contains a larger class, and I can't refactor v
due to other dependencies in the code base.在我的实际情况中, v
包含一个更大的类,由于代码库中的其他依赖关系,我无法重构v
。 Also, in the real case I'm not using std::set
but it simplifies the example.此外,在实际情况下,我没有使用std::set
但它简化了示例。 Here are two example classes A
and B
that I know don't work, and I do understand why, but hopefully will illustrate what I'm trying to do:这是我知道不起作用的两个示例类A
和B
,我确实理解为什么,但希望能说明我正在尝试做的事情:
#include <set>
#include <vector>
using namespace std;
struct A
{
A(initializer_list<float> init) : v(init)
{
for(size_t i = 0; i < init.size(); ++i)
{
s.insert(i);
}
}
struct Less
{
Less(const vector<float>& v) : v(v) {};
bool operator()(size_t i, size_t j)
{
return v[i] < v[j];
}
const vector<float>& v;
};
vector<float> v;
set<size_t, Less> s;
};
struct B
{
B(initializer_list<float> init) : v(init)
{
for(size_t i = 0; i < init.size(); ++i)
{
s.insert(i);
}
}
template<const vector<float>& v>
struct Less
{
bool operator()(size_t i, size_t j)
{
return v[i] < v[j];
}
};
vector<float> v;
set<size_t, Less<v>> s;
};
int main()
{
A a = {1., 2., 3.};
B b = {1., 2., 3.};
}
In both cases s
contains indicies that refer to elements in v
, and Less
is trying to compare the values in v
using those indices.在这两种情况下s
包含引用v
元素的索引, Less
尝试使用这些索引比较v
的值。 Is there a way to do this that I'm not seeing?有没有办法做到这一点,我没有看到?
Your A
approach is almost correct.你的A
方法几乎是正确的。 It just needs 2 fixes:它只需要 2 个修复:
bool operator()(size_t i, size_t j)
should be const
. bool operator()(size_t i, size_t j)
应该是const
。s
must have a configured functor passed to it during construction. s
必须在构造期间传递给它的已配置函子。struct A
{
A(initializer_list<float> init) : v(init), s(v)
{
for(size_t i = 0; i < init.size(); ++i)
{
s.insert(i);
}
}
// These must be manually defined if you need them, the default
// ones won't be correct.
A(const A&) = delete;
A& operator=(const A&) = delete;
struct MyLess
{
MyLess(const vector<float>& v) : v(v) {};
bool operator()(size_t i, size_t j) const
{
return v[i] < v[j];
}
const vector<float>& v;
};
vector<float> v;
set<size_t, MyLess> s;
};
I'm using unordered_map so maybe your idea will still work?我正在使用 unordered_map 所以也许你的想法仍然有效?
Yes, the same principle applies to std::unordered_set
.是的,同样的原则适用于std::unordered_set
。 You just have to pass in both hash
and key_equal
during construction.您只需要在构造过程中传入hash
和key_equal
。 Check out the documentation to identify the correct constructor to invoke.查看文档以确定要调用的正确构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.