如何根据已排序索引的向量对 std::set 索引进行排序?
Posted
技术标签:
【中文标题】如何根据已排序索引的向量对 std::set 索引进行排序?【英文标题】:How to sort std::set of indices according to the vector of sorted indices? 【发布时间】:2020-06-15 13:45:02 【问题描述】:我有一个类MyClass
,它使用一些双精度值beta
,作为类成员存储在它的成员函数g
中。它对它们进行排序并将排列存储在类成员std::vector<int> sorted_beta_ind
中:
double MyClass::g()
// ...
sorted_beta_ind.resize(n);
for(unsigned int i=0; i<n; ++i)
sorted_beta_ind[i] = i;
std::sort(sorted_beta_ind.begin(), sorted_beta_ind.end(),
[this] (const int &a, const int &b) ++op_cmp; return beta[a] > beta[b];);
// ...
接下来,我想在另一个成员函数f
中有几个有序的索引集,它将以与sorted_beta_ind
中相同的顺序存储索引。我正在尝试使用 std::set
对象,因此,我需要一个比较器。我想出的最佳解决方案是 lambda 函数
double MyClass::f()
auto ind_comp = [&order = sorted_beta_ind] (const int &a, const int &b)
int pos_a = ~0, pos_b = ~0;
for(unsigned int i=0; i<order.size(); ++i)
if(order[i] == a)
pos_a = i;
if(order[i] == b)
pos_b = i;
return pos_a < pos_b;
;
std::set<int, decltype(ind_comp)> d0, d1;
// the rest of the function which uses std::union and std::instersection
但是在构建项目时我得到了
error: use of deleted function ‘MyClass::f()::<lambda(const int&, const int&)>& MyClass::f(int**, int)::<lambda(const int&, const int&)>::operator=(const MyClass::f()::<lambda(const int&, const int&)>&)’
这种方法行得通,还是我应该尝试完全不同的方法?
【问题讨论】:
如果您希望集合包含按与向量相同的顺序排序的索引,为什么不使用相同的比较函子呢? example 你用这组索引做什么?map<index, object>
不会吗?
【参考方案1】:
像您的那样捕获 lambda 表达式不是 DefaultConstructible。这正是std::set
试图做的事情,除非它接收到一个可以作为构造函数调用参数复制的比较器对象。那就是:
std::set<int, decltype(ind_comp)> d0, d1;
这里std::set
只知道比较器的类型,并将尝试使用其默认构造函数来构造一个。相反,它应该是:
std::set<int, decltype(ind_comp)> d0(ind_comp), d1(ind_comp);
// ~~~~~~~^ ~~~~~~~^
【讨论】:
@Verloren 没关系,没有注意到你的 lambda 有捕获。 PiotrSkotnicki,是的,我的错。 @Verloren 这个数组再次执行两个集合的default初始化。您需要指定这两个元素,例如,using S = std::set<int, decltype(ind_comp)>; S d[2] S(ind_comp), S(ind_comp) ;
不是那一行 :) 但我想你很可能最终会尝试将一组复制分配给另一组,是吗?
错误消息肯定会继续说“需要来自”并给出代码中尝试复制分配 lambda 表达式的行号
@Verloren 它最终应该指向您的代码。你没有显示完整的代码,所以我不知道出了什么问题。 It compiles以上是关于如何根据已排序索引的向量对 std::set 索引进行排序?的主要内容,如果未能解决你的问题,请参考以下文章