c++ - 使用std::sort对C风格的2D数组进行部分排序

标签 c++ arrays sorting c++11

我遇到了有关对整数数组的前2行进行排序的this question,想到的最明显的方法是使用std::sort,因此我提出了一个解决方案,例如:

int mat[][3] = { {4, 5, 3},
                 {6, 8, 7},
                 {9, 5, 4},
                 {2, 1, 3} }; 


std::sort(std::begin(mat[0]), std::end(mat[1])); //sprting the first two rows

如您所愿see here,它可以正常工作而不会出现错误或警告。

同时C++中的@Jarod42 pointed out that this is pedantically undefined behaviour是因为它们是两个不同数组的指针。

我倾向于这种做法,因为在C中这将是一种很好的方法(当然不使用std::sortstd::beginstd::end),使用一种类似的方法来在线访问数组,因为将二维数组存储在C中。

我们同意,它将是未定义的行为but as @SergeBallesta remebered,几乎所有编译器都接受此方法,因此应该使用它吗?

而如果是one uses a int(*mat)[3] pointer to array,那么以这种方式使用std::sort仍然是学究性的UB呢?
//...
srand(time(0));

int(*mat)[3] = (int(*)[3])malloc(sizeof(int) * 4 * 3);
//or int(*mat)[3] = new int[4][3];

for(int i = 0; i < 4 ; i++)
    for(int j = 0; j < 3; j++)
        mat[i][j] = rand() % 9 + 1;

std::sort(std::begin(mat[0]), std::end(mat[1])); //sorting the first two rows
//...

最佳答案

问题出在标准定义数组类型(8.3.4 [dcl.array])的方式上:

An object of array type contains a contiguously allocated non-empty set of N subobjects of type T.



但它没有明确表示可以将连续分配的相同类型的对象集用作数组。

出于兼容性的原因,我知道所有编译器都接受这种互惠性,但从理论的 Angular 来看,它在标准中并未明确定义,并且是未定义的行为。

不互惠背后的理由是,程序应代表模型。并且在模型中,对象没有理由同时成为成员或一个以上数组。因此,该标准不允许这样做。实际上,我在处理2D数组时遇到的所有(实际)用例就好像是1D数组一样,都是低级优化的原因。在现代C++中,程序员不应在意低级优化,而应由编译器来处理。

以下仅是我的意见。

当您发现自己像处理1D数组一样处理2D数组时,应该问问自己原因。如果您使用的是遗留代码,请不要担心:编译器当前会接受它,即使将来以特殊选项为代价,它甚至可能会继续使用。

但是,如果您正在编写新代码,则应尝试向后(或向后)移动一步,并想知道它在模型级别代表什么。大多数情况下,您会发现数组本质上是1D或2D,但不是两者都是。完成此操作后,如果性能并不重要,请尝试始终以一致的方式进行处理。甚至更好,请尝试使用标准库中的容器而不是原始数组。

如果您在性能至关重要的代码中说任何连续分配的对象集都是一个数组,那么这将带来重要的好处,请这样做并为以后的维护者记录下来。但是只有在分析后才这样做...

关于c++ - 使用std::sort对C风格的2D数组进行部分排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62001869/

相关文章:

c++ - MFC 应用程序 : How to add a set of controls to an single document application?

c - 为什么 arr[1] 打印的内容看起来像是 arr[0] ?

javascript - 如何对不可变映射内的项目进行排序(交换)?

c - 尝试在 C 中打印 10 行,每行 100 个数组值

c++ - 程序在冒泡排序时崩溃?

c++ - 在 OpenCV 中结合两个仿射变换矩阵

c++ - 对于输入迭代器,为什么 a == b 并不意味着++a ==++b?

c++ - 从 C++ 函数返回 char 数组到 tcl

javascript - 访问 Vue JS 实例监视对象中的 $refs 数组

c++ - C++中的双向选择排序