使用C++ 11中的std :: sort和lambda函数对动态分配的多维C数组进行排序

Whi*_*der 4 c++ arrays sorting lambda c++11

我正在尝试std::sort使用lambda 使用自定义排序函数对2D动态分配的数组进行排序.numFaces是在程序开始时确定的整数值,在程序的生命周期内不会更改.这是我目前的做法.

float(*data)[24] = new float[numFaces][24];
std::sort(data, data + numFaces,  [](float (&A)[24], float (&B)[24]) -> bool
{
    return comparison(A, B); // Pseudo
});
Run Code Online (Sandbox Code Playgroud)

该程序无法使用此错误进行编译:

数组类型'float [24]'不可赋值

因为我在lambda声明中指定参数应该是引用,所以我不明白为什么编译器会产生这个错误消息.我正在使用Microsoft的Visual Studio Community Edition 2015中的VC++编译器. 这是一个整个日志的快速pastebin

第38行是lambda函数声明的结束括号.

我知道我可以通过几种不同的方式解决这个问题,但如果有办法让这项工作成功,我宁愿继续这样做.如果您对另一个解决方案有建议,该解决方案可以连续存储数据并在这些28个浮点数组中排序,我也很高兴听到这个问题.

我可以解决当前问题的方法,这会在应用程序中引入其他问题和/或更大的延迟:

  • 使用qsortvoid指针,以相同的方式投射它们并进行排序.我有点不确定这是否会引入更多的延迟,当std::sort没有一回事,如果我使用,这将有容器中的信息std::vector秒.
  • 使用std::sort嵌套的std::vectors.数据并不总是连续存储在内存中,这反过来又迫使我每次对矢量进行排序时都创建数据的副本.我测试了这个,并使用VS调试器检查了内存中的位置,但我再次不确定这不能以某种方式解决.
  • 使用std::vector带有所需数据的自定义类/结构.如果我的问题没有简单的解决方案,我会这样做或者在没有任何STL调用的情况下进行排序.

微小的注意:上面代码标签中的代码被剥夺了不必要的代码.因此,pastebin有点不同.


快速回顾一下解决方案的问题:

std::sort通过将一个元素分配给另一个元素来重新排列您正在排序的元素.因此,元素必须是可分配的,而C风格的数组则不是.有很多方法可以解决这个问题,但是如果你需要将数据连续存储在内存中,你需要一个类型来保存数组所拥有的数据; 不多也不少.std::array人们在评论中指出,这是完美的类型.这是一个示例解决方案:

#include <vector>
#include <array>

std::vector<std::array<float, 24>> data;
Run Code Online (Sandbox Code Playgroud)

并通过以下std::sort电话:

std::sort(data.begin(), data.end(), [](const std::array<float, 24> &A, const std::array<float, 24> &B) -> bool
{
    return A[0] < B[0]; // Sample sort condition
});
Run Code Online (Sandbox Code Playgroud)

Naw*_*waz 5

首先,基础知识:

float(*data)[24] = new float[numFaces][24];
Run Code Online (Sandbox Code Playgroud)

在这里你定义data为动态数组的大小numFaces,它的每个元素都是一个静态大小的数组24,这意味着data[0]是一个大小的数组24,data[1]是一个大小的数组,24依此类推.

所以分拣data使用std::sort装置排序的元素- ,data[0],data[1],,data[2] -这是静态大小阵列本身....data[numFaces-1]

因为我在lambda声明中指定参数应该是引用,所以我不明白为什么编译器会产生这个错误消息.

错误是因为数组不能在C++(以及C语言)中分配,因为错误消息清楚地说明了这一点.为了对元素进行排序,std::sort需要重新排列元素,并且仅通过赋值来完成 - 库没有使用其他方法.它使用迭代器,并在某处执行此操作:

 *it1 =  *it2;   //it1 and it2 point to arrays
Run Code Online (Sandbox Code Playgroud)

这基本上相当于此,

data[i1] = data[i2];  
Run Code Online (Sandbox Code Playgroud)

由于data[i1]是一个数组(静态大小24),上面的赋值是无效的.如果你这样做,你会得到同样的错误:

float a[24], b[24];

a = b; //error
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • @Whitehooder,`std :: array <float,24>`的对象是可分配的,与"普通"数组不同.这些动态阵列是否符合您的要求?语法也可能更容易理解......`使用Face = std :: array <float,24>;` (3认同)