【问题标题】:sort predicate is not passing references to indexed objects?排序谓词没有传递对索引对象的引用?
【发布时间】:2018-09-17 22:30:52
【问题描述】:

我有几个并行数组。我不想创建一个将它们全部组合在一起的新数组,所以我创建了一个索引数组,我想根据其中一个并行数组内容对其进行排序。但是,如果我尝试获取传递索引的索引,它们似乎不是对原始向量的引用。

例如:

#include <iostream>
#include <vector>
#include <algorithm>
#include <assert.h>

using namespace std;

int main()
{

    vector<int> original = { 4, 3, 5, 2, 7 };
    vector<size_t> indices;
    size_t length = original.size();
    indices.reserve(length);
    for(size_t i = 0; i < original.size(); ++i) {
      indices.push_back(i);
    }

    sort(indices.begin(), indices.end()
      , [&] (size_t& lhs, size_t& rhs) {
        assert(&indices.front() <= &lhs && &lhs <= &indices.back());
        assert(&indices.front() <= &rhs && &rhs <= &indices.back());
        size_t iLhs = &lhs - &indices.front();
        size_t iRhs = &rhs - &indices.front();
        return original[iLhs] < original[iRhs];
    });

    for(auto index : indices) {
        cout << original[index] << endl;
    }

    return 0;
}

Demo

失败并显示消息:

a.out: main.cpp:22: main()::: 断言 `&indices.front() 

为什么会这样?这是否意味着std::sort 在明确告知在谓词中使用引用时会创建对象的副本?这不是效率低吗?

【问题讨论】:

  • @Justin,是的,我以前做过。想确保我得到正确的指示。与问题无关。如果真的需要,我会更改它。
  • &amp;indices.front() &lt;= &amp;lhs 你不应该比较指针,而是比较索引的值。
  • std::iota 可能有助于构建 indices
  • 不要求只在引用范围内的情况下调用比较器。 std::sortstd::sort 内的局部变量上调用它是完全有效的。这就是正在发生的事情:coliru.stacked-crooked.com/a/bf7b4d862a8cdab9
  • std::sort 不复制任何内容。但是,它可以随意移动元素到局部变量中。

标签: c++ visual-c++ stl c++14 std


【解决方案1】:

我不清楚你为什么需要这些线条

    size_t iLhs = &lhs - &indices.front();
    size_t iRhs = &rhs - &indices.front();

完全没有。删除它们。简化您的呼叫

sort(indices.begin(), indices.end(),
     [&] (size_t lhs, size_t rhs) {
         return original[lhs] < original[rhs];
     });

【讨论】:

  • 哦,是的。不知道我在想什么。嘘。
  • 仍然在问这个问题。对象是否在实际排序之前被复制?
  • @Adrian,哪些对象? original中的对象?
  • original 保持不变(甚至可以是const)。
  • @Adrian,会有复制,但不会是不必要的复制。没有其他方法可以对对象的向量/数组进行排序。
猜你喜欢
  • 1970-01-01
  • 2019-12-20
  • 2015-03-06
  • 1970-01-01
  • 2016-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多