使用sort排序二维数组时触发array初始化等编译错误
二维数组自定义排序的编译错误原因及修复
编写竞赛题程序时,需要对二维数组按规则排序:从最后一个元素开始降序比较,依次往前。使用如下代码时出现编译错误,提示“array must be initialized with a brace-enclosed initializer”和“invalid array assignment”,暂时用struct替代,想知道代码具体问题:
#include <iostream> #include <algorithm> using namespace std; bool compare(int a[3], int b[3]) { for (int i=2; i>=0; i--) { if (a[i] != b[i]) { return a[i] > b[i]; } } return false; } int main() { int arr[3][3] = {{1, 2, 3}, {1, 2, 4}, {1, 2, 5}}; sort(arr, arr+3, compare); }
错误信息如下:
[ { "resource": "/c:/msys64/ucrt64/include/c++/13.2.0/bits/stl_algo.h", "owner": "cpptools", "severity": 8, "message": "array must be initialized with a brace-enclosed initializer", "source": "gcc", "startLineNumber": 1822, "startColumn": 17, "endLineNumber": 1822, "endColumn": 17 }, { "resource": "/c:/msys64/ucrt64/include/c++/13.2.0/bits/stl_algo.h", "owner": "cpptools", "severity": 8, "message": "invalid array assignment", "source": "gcc", "startLineNumber": 1824, "startColumn": 24, "endLineNumber": 1824, "endColumn": 24 }, { "resource": "/c:/msys64/ucrt64/include/c++/13.2.0/bits/stl_heap.h", "owner": "cpptools", "severity": 8, "message": "array must be initialized with a brace-enclosed initializer", "source": "gcc", "startLineNumber": 262, "startColumn": 18, "endLineNumber": 262, "endColumn": 18 }, { "resource": "/c:/msys64/ucrt64/include/c++/13.2.0/bits/stl_heap.h", "owner": "cpptools", "severity": 8, "message": "invalid array assignment", "source": "gcc", "startLineNumber": 263, "startColumn": 17, "endLineNumber": 263, "endColumn": 17 }, { "resource": "/c:/msys64/ucrt64/include/c++/13.2.0/bits/stl_heap.h", "owner": "cpptools", "severity": 8, "message": "array must be initialized with a brace-enclosed initializer", "source": "gcc", "startLineNumber": 355, "startColumn": 22, "endLineNumber": 355, "endColumn": 22 } ]
核心问题原因
C++里,数组作为函数参数传递时会自动退化为指针,所以你的compare函数参数int a[3]实际等价于int* a,这部分本身没问题。真正的问题出在std::sort的操作对象上:
你传入sort的arr是int[3][3]类型,它的每个元素是int[3]数组。而C++的原生数组是不可赋值、不可复制的类型——sort内部排序过程中需要对元素做赋值、创建临时变量等操作,这就触发了编译错误:
invalid array assignment:尝试直接赋值数组,而数组不支持这种操作array must be initialized with a brace-enclosed initializer:尝试用数组类型创建临时变量,但数组只能用初始化列表初始化,无法直接构造
修复方案
不用struct也能解决,两种常用方法:
方案1:用std::array替代原生数组
std::array是C++11的容器,既保留了原生数组的性能,又支持赋值、复制等容器操作,完美兼容std::sort:
#include <iostream> #include <algorithm> #include <array> using namespace std; bool compare(const array<int, 3>& a, const array<int, 3>& b) { for (int i = 2; i >= 0; --i) { if (a[i] != b[i]) { return a[i] > b[i]; } } return false; } int main() { array<array<int, 3>, 3> arr = {{{1, 2, 3}, {1, 2, 4}, {1, 2, 5}}}; sort(arr.begin(), arr.end(), compare); // 输出验证排序结果 for (const auto& row : arr) { for (int num : row) { cout << num << " "; } cout << endl; } }
方案2:用指针数组间接排序(适合竞赛场景)
如果坚持用原生数组,可以把每行的地址存到一个指针数组里,排序这个指针数组,避免直接操作不可赋值的数组元素:
#include <iostream> #include <algorithm> using namespace std; const int COL = 3; bool compare(const int* a, const int* b) { for (int i = COL - 1; i >= 0; --i) { if (a[i] != b[i]) { return a[i] > b[i]; } } return false; } int main() { int arr[3][3] = {{1, 2, 3}, {1, 2, 4}, {1, 2, 5}}; // 构造指针数组,每个元素指向原二维数组的一行 int* ptr_arr[3] = {arr[0], arr[1], arr[2]}; sort(ptr_arr, ptr_arr + 3, compare); // 输出排序后的结果 for (const auto* row : ptr_arr) { for (int i = 0; i < COL; ++i) { cout << row[i] << " "; } cout << endl; } // 如果需要修改原二维数组的元素顺序,可以在排序后把指针指向的内容复制回去 }
内容的提问来源于stack exchange,提问作者Vex Ave
相关产品推荐
相关产品推荐

