问题
I cannot seem to sort a 2 dimensional c array with std::sort. I can however sort a one dimensional array. This is in a case where I am being handed a c array in a c++ program and am hoping to sort without copying it over to a std::array. Maybe there is some way to turn it into a std::array without copying it? That sounds doubtful to me as any std::array would then call a destructor on memory that it does not own.
Sorting One dimensional c style array works just fine:
int len = 5;
auto one_dim_less = [](int a, int b){
return a < b;
};
int one_dim[] = {4, 0, 3, 1, 2};
std::sort(one_dim, one_dim + len, one_dim_less);
Attempting to sort two dimensional c style array by second number does not compile:
int len = 5;
auto two_dim_less = [](int a[2], int b[2]){
return a[1] < b[1];
};
int two_dim[][2] = {{1,8}, {2,4}, {3,10}, {4,40}, {5,1}};
std::sort(two_dim, two_dim + len, two_dim_less);
回答1:
Maybe there is some way to turn it into a
std::array
without copying it?
Perhaps not turning into a std::array
per se, but an alternative approach might be to cast the 2D C-style arrays into a std::array
reference just for the sorting. Doing so in reliance on the standard saying an std::array
representation in memory at least begins with its C-style array equivalent. See here under [array.overview§2]:
An array is an aggregate that can be list-initialized with up to N elements whose types are convertible to T.
In practice, the following usage of reinterpret_cast
is most probably safe, but do note that unless there is a special exception for it somewhere in the standard, it would formally be undefined behaviour:
#include <algorithm>
#include <array>
#include <iostream>
int main() {
auto two_dim_less = [](std::array<int, 2>& a, std::array<int, 2>& b) {
return a[1] < b[1]; };
int two_dim[][2] = {{1, 8}, {2, 4}, {3, 10}, {4, 40}, {5, 1}};
std::array<std::array<int, 2>, 5>& arr =
*reinterpret_cast<std::array<std::array<int, 2>, 5>*>(&two_dim);
std::sort(arr.begin(), arr.end(), two_dim_less);
for (int i = 0; i < 5; i++)
std::cout << two_dim[i][0] << ", " << two_dim[i][1] << '\n';
return 0;
}
Output:
5, 1
2, 4
1, 8
3, 10
4, 40
Regarding the use of std::qsort()
, note that it is potentially slower than std::sort() due to the latter allowing to inline the comparisons while the former doesn't.
回答2:
std::sort()
requires the objects it's used to sort to be MoveAssginable.
Arrays are not MoveAssginable (nor assignable at all).
Try using an array of structures or std::pair
s instead.
来源:https://stackoverflow.com/questions/52347204/sort-2-dimensional-c-array-with-stdsort