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,然后将迭代器传递给sortedsort。如果您确实解决了这个问题,那么请为@lubgr 提到的排序谓词准备一个非常长的错误。 :) sorted = std::sort(idx_correlations.begin(),... -- 你对这段代码的意图是什么?这不是std::sort 的工作方式。 排序对将具有以下标准:所有对在此处的第一个 (x,y) 排序 x,如果相等,则按其第二个 (x,y) 在此处的 y 排序。 @Cece -- 排序的类型无关紧要 -- 它们可以是简单的 intdoublespairs 或小部件 -- 没关系. std::sort 谓词采用该类型的两个参数。你有两个值,你应该返回truefalse,这取决于第一个值是否应该放在第二个值之前。也许如果您使用现代 C++ 语法并使用 auto,事情会更容易理解:std::sort(idx_correlations.begin(), idx.correlations.end(), [](auto&amp; val1, auto&amp; val2)...auto 是什么取决于向量持有的类型。 【参考方案1】:

你有两个问题:

    sort 不返回已排序范围的副本。它修改提供的范围。如果您想保留原件,请先复制一份,然后对其进行分类。

    std::sort的第三个参数是两个值之间的比较器,有“小于”的意思。也就是说,“a 在 b 之前吗?”为了保持简短,我在 lambda 中用 auto 替换了您的 pair&lt;...&gt; 类型,但它会被推断为正在排序的“任何类型的事物”。

注意,如果要减少,只需在比较两个元素时将 lambda 中的 &lt; 更改为 &gt;

可能的修复:

    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。这种方式是否专注于浮点值进行排序? 这部分&amp;std::pair&lt;int, float&gt;::second 这么说。 std::greater 表示降序。

以上是关于std::vector<std::pair<int, float>> 和 void 错误的主要内容,如果未能解决你的问题,请参考以下文章

std::pair<vector<int>, double> 的初始化列表

如何将两个 std::vector 与 std::pair 组合成一个 std::vector

数组的 C++ 向量

如何仅对 std::vector 中的子集进行排序?

如何在函数结束时有效释放向量内存? [关闭]

修复这个 std::async 调用