std::vector<std::pair<int, float>> 和 void 错误
Posted
技术标签:
【中文标题】std::vector<std::pair<int, float>> 和 void 错误【英文标题】:std::vector<std::pair<int, float>> and void error 【发布时间】:2021-09-03 04:38:43 【问题描述】:我想按降序对 m_correlationValues 进行排序并获取排序列表的 ID。我有这个错误。我会感谢你的帮助。 'operator=' 不匹配(操作数类型为 'std::vector<:pair float>>' 和 'void') 返回 idx_correlation.second; );
void MatrixCanvas::SortMatrix()
int naxes = (int) m_correlationData.size();
std::vector<std::pair<int,float>> idx_correlations;
std::vector<std::pair<int,float>> sorted;
std::vector<int> idxs(naxes);
for(int idx =0; idx<naxes;idx++)
idx_correlations[idx] = std::make_pair(idx, m_correlationValues[chosen_row_id][idx]);
// Wrong
sorted = std::sort(idx_correlations.begin(),
idx_correlations.end(),
[](std::pair<int,float> &idx_correlation)
return idx_correlation.second; );
// this will contain the order:
for(int i =0; i<naxes;i++)
idxs[i] = sorted[i].first;
【问题讨论】:
您的排序谓词必须 (1) 具有不同的签名,因为它被调用时带有两个要比较的参数,并且 (2) 返回一个bool
指示是否将第一个参数视为“更少" 比第二个。
std::sort
不返回任何内容。它排序到位。当它返回 idx_correlations
时将被排序。如果您想保持未排序,那么您应该先制作一个副本,例如sorted = idx_correlations
,然后将迭代器传递给sorted
到sort
。如果您确实解决了这个问题,那么请为@lubgr 提到的排序谓词准备一个非常长的错误。 :)
sorted = std::sort(idx_correlations.begin(),...
-- 你对这段代码的意图是什么?这不是std::sort
的工作方式。
排序对将具有以下标准:所有对在此处的第一个 (x,y) 排序 x,如果相等,则按其第二个 (x,y) 在此处的 y 排序。
@Cece -- 排序的类型无关紧要 -- 它们可以是简单的 int
、doubles
、pairs
或小部件 -- 没关系. std::sort
谓词采用该类型的两个参数。你有两个值,你应该返回true
或false
,这取决于第一个值是否应该放在第二个值之前。也许如果您使用现代 C++ 语法并使用 auto
,事情会更容易理解:std::sort(idx_correlations.begin(), idx.correlations.end(), [](auto& val1, auto& val2)...
。 auto
是什么取决于向量持有的类型。
【参考方案1】:
你有两个问题:
sort 不返回已排序范围的副本。它修改提供的范围。如果您想保留原件,请先复制一份,然后对其进行分类。
std::sort
的第三个参数是两个值之间的比较器,有“小于”的意思。也就是说,“a 在 b 之前吗?”为了保持简短,我在 lambda 中用 auto
替换了您的 pair<...>
类型,但它会被推断为正在排序的“任何类型的事物”。
注意,如果要减少,只需在比较两个元素时将 lambda 中的 <
更改为 >
。
可能的修复:
auto sorted = idx_correlations; // full copy
std::sort(sorted.begin(),
sorted.end(),
[](auto const & left, auto const & right)
return left.first < right.first; );
之后,sorted
将是一个已排序的向量,而 idx_correlations 将保持不变。当然,如果您不介意修改原始集合,则无需制作此副本(您可以获取 idx_correlations 的开始/结束。
【讨论】:
谢谢!我现在明白其中的逻辑了。【参考方案2】:所以我在您的代码中看到的主要问题是,您希望 std::sort
返回排序后的向量,但这不是它的工作原理。
https://en.cppreference.com/w/cpp/algorithm/sort
在您的情况下,解决方案是从原始向量中取出排序后的向量,即。 sorted = idx_correlations
然后对新向量进行排序。
sorted = idx_correlations;
std::sort( sorted.begin(), sorted.end(), your_comparator... );
这样可以解决问题,同时还能保持原始向量。
更新:另一个问题是您的比较器将有两个参数而不是一个(要比较两个元素以进行排序)。
【讨论】:
谢谢!我现在明白其中的逻辑了。 没问题,我的荣幸【参考方案3】:其他答案包括正确使用std::sort
,我希望展示具有投影功能的C++ 20 std::rannges::sort
与您尝试做的事情接近:
std::vector<std::pair<int, float>> idx_correlations;
.....
auto sorted = idx_correlations;
std::ranges::sort(sorted, std::greater, &std::pair<int, float>::second);
https://godbolt.org/z/4rzzqW9Gx
【讨论】:
谢谢!我的目标是根据对中的浮点数进行排序,因为稍后我将使用排序的 id。这种方式是否专注于浮点值进行排序? 这部分&std::pair<int, float>::second
这么说。 std::greater
表示降序。以上是关于std::vector<std::pair<int, float>> 和 void 错误的主要内容,如果未能解决你的问题,请参考以下文章
std::pair<vector<int>, double> 的初始化列表