c++ - 为什么 std::stable_sort() 的比较器函数的参数必须设置为常量?
问题描述
各位程序员大家好,我正在解决一个需要以稳定顺序排序的 leetcode 问题。
问题链接:https ://leetcode.com/problems/rearrange-words-in-a-sentence/submissions/
我注意到 std::stable_sort() 的比较器函数的参数必须设置为常量,否则会生成以下编译时错误。
下面是生成编译时错误的代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void display(vector<string> &a);
bool compare(string &s1, string &s2);
int main() {
vector<string> a = {"abc", "defgh", "ijk"};
// sorting vector<string> in stable order
// error will be generated
std::stable_sort(a.begin(), a.end(), compare);
display(a);
return 0;
}
// argument strings should be made constants???
bool compare(string &s1, string &s2) {
return s1.length() < s2.length();
}
void display(vector<string> &a) {
for(int i=0; i<=a.size()-1; i++) {
cout << a[i] << " ";
}
cout << "\n";
return ;
}
// errors generated
/*
error: binding reference of type ‘std::__cxx11::basic_string<char>&’ to ‘const
std::__cxx11::basic_string<char>’ discards qualifiers
177 | { return bool(_M_comp(*__it, __val)); }
error: binding reference of type ‘std::__cxx11::basic_string<char>&’ to ‘const
std::__cxx11::basic_string<char>’ discards qualifiers
215 | { return bool(_M_comp(__val, *__it)); }
*/
我尝试谷歌搜索,但找不到任何东西。我搜索了 Stack Overflow 并遇到了一个问题,但无法理解那里解释的原因。
堆栈溢出答案链接:
https://stackoverflow.com/a/45905608/13331053
任何帮助表示赞赏。提前致谢!
解决方案
因为这就是函数所需要的。从 cppreference 引用std::stable_sort
(强调我的):
比较函数的签名应该等同于以下内容:
bool cmp(const Type1 &a, const Type2 &b);
虽然签名不需要
const &
,但函数不得修改传递给它的对象,并且必须能够接受所有类型的值(可能)const
并且Type1
无论Type2
值类别如何(因此,Type1 &
不允许[,也Type1
不允许Type1
move 等价于副本 (C++11 起)])。
您的函数必须接受const
参数,并且非常量引用类型不符合此要求。因此,您的compare
函数应如下所示:
bool compare(const string &s1, const string &s2);
GCC 完全可以接受非常量版本std::sort
:https ://godbolt.org/z/S2tL44 ,尽管它的std::sort
要求与std::stable_sort
. 我假设它根本没有在任何地方检查,并且std::sort
实现不依赖于常量,但std::stable_sort
确实如此。为什么?这将是源代码(或标准库维护者)的问题。
const&
在任何情况下,始终在此类函数中使用参数以让编译器捕获对对象的任何意外修改并确保它适用于每个编译器,这将更安全、更便携。
推荐阅读
- r - 随着时间的推移计算具有起源和演变的数值特征
- postgresql - 如何使用子查询在 PostgreSQL 中创建唯一索引?
- bash - fold:使用参数运行脚本时列数无效
- amazon-web-services - 如何使用 Terraform 附加或删除安全组的入口/出口规则?
- node.js - 静音控制台文本输入
- javascript - 在另一个网站上填写我在我的网站上输入的表格
- android - 如何根据android中的firebase身份验证状态执行条件导航
- docker - 如何将在同一端口上侦听的堆栈的多个实例部署到 Docker Swarm(在反向代理之后)?
- xamarin - 如何将 Linux 库添加到我的 Xamarin 项目
- excel - 如何将excel连接到sharepoint并允许多个用户使用excel文件