如何std::sort
用于对固定大小的数组进行排序(例如typedef XXX char[16]
)?我尝试了一些方法,但似乎不起作用。例如我当前的代码如下所示:
#include <iostream>
#include <algorithm>
#include <cstring>
typedef char t_name[16];
bool compareNames(const t_name& name1, const t_name& name2) {
return strcmp(name1, name2) < 0;
}
int main() {
t_name names[] = {
"bruno",
"karl",
"adrian",
"yanick"
};
int numNames = sizeof(names) / sizeof(names[0]);
std::sort(names, names + numNames, compareNames);
for (int i = 0; i < numNames; i++) {
std::cout << names[i] << std::endl;
}
return 0;
}
不幸的是,这段代码无法编译。可能是因为普通赋值不适用于数组类型。错误(不太可读)可以在这里看到: https ://godbolt.org/z/Ms54P7ozj
也许有人知道如何实现这一点?不幸的是,我无法控制要排序的数组类型,因此无法更改。
您不能使用
std::sort
一系列 C 样式数组,因为它们不满足类型要求:std::swap
数组有重载)您可以通过对数组进行排序来解决这个问题
std::string_view
:注 1:在 C++17 之前,您可以使用
std::string
代替std::string_view
。注 2:您仍然可以提供自定义比较器。如果您想按降序排序,请提供
std::greater
/std::ranges::greater
例如。包裹
t_name
在一个struct
这是 @PaulMcKenzie 在他的评论中建议的包装解决方案。保罗抢先一步。他发帖时我正在编码。
在他的问题下面的评论中,OP 解释说它
t_name
来自图书馆,并且他无法控制它。这对他来说意味着std::string
或者std::string_view
只是没有选择。包装
t_name
在一个结构体中确实可以让你获得OP所要求的排序能力。您可以创建 的内置数组t_name_struct
,并使用std::sort
它们。然而,如果 OP 使用的库要求他与内置数组进行交互
t_name
,而不是t_name
一次与单个对象交互,那么这种解决方案就会有问题。在这种情况下,需要某种从一种数组类型转换为另一种数组类型的方法。有了这些注意事项,使用包装器(例如
t_name_struct
.使用结构体的一个好处是您可以定义
operator<
来处理比较。这允许您在调用中省略比较器sort
。由于数组定义在与 的调用相同的范围内可用
sort
,因此您可以使用std::begin(names)
和std::end(names)
来获取数组的迭代器。我已经在调用中使用了这些sort
。出于同样的原因,您可以使用range-for循环遍历数组的元素。这样,您就不需要包含 的计算
numNames
。顺便说一句,当您确实需要内置数组的大小时,您现在可以使用std::size
来获取它。sizeof
返回字节数;std::size
,元素数量。总而言之,整个事情都清理得很好。
这是输出:
使用宇宙飞船
operator<=>
如果 C++20 可用,则可以替换
operator<
为 spaceshipoperator<=>
。鉴于 的三向性质strcmp
,为它编写一个太空飞船操作符是很自然的。这:
意味着所有字符串的长度正好是 15 个字符加上一个空字符。
names
我想我们可以通过用足够的空格或空字符填充数组中的所有项目来修复它。但这作为声明有点尴尬。由于您正在处理字符串文字,因此整个程序(包括 C 和 C++ 模式的混合)可以是这样的:现在,为了使其更像 C++,我们可以利用 std::string,然后利用 std::string 具有内置
<
运算符重载。那么我们就不需要显式的比较函数。但是,如果您正在执行一些自定义操作,例如按降序而不是升序排序,则可以使用 lambda 来执行此操作:
只是一个概念证明,您可以
names
使用适当的包装器对原始数组中的 char 数组进行排序,而无需诉诸std::string
或std::string_view
更改现有的数据结构。但是,如果可能的话,请使用其他答案之一中的解决方案,因为如果您不受 typedef 的限制,它们是解决问题的更好、更规范的方法。演示: https: //godbolt.org/z/77GdPGx9x