为何使用泛型lambda对string向量执行std::sort无效?
为什么泛型lambda作为std::sort比较器时无法正确排序?
示例代码
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; bool sortByName(const auto& first, const auto& second) { return first < second; } void print(const auto& vec) { for(const auto& s : vec) cout << s << ", "; cout << endl; } int main() { vector vec2 = {"sam", "zach", "adam", "peter"}; print(vec2); auto cmp = [](const auto& s1, const auto& s2) { return s1 < s2; }; std::sort(vec2.begin(), vec2.end(), cmp); // line (1) print(vec2); auto cmp2 = [](const string& s1, const string& s2) { return s1 < s2; }; std::sort(vec2.begin(), vec2.end(), cmp2); // line (2) print(vec2); }
运行结果
- 使用
cmp2的std::sort可正确排序向量,结果为:adam, peter, sam, zach, - 使用
cmp的std::sort保持向量元素的原始顺序,结果为:sam, zach, adam, peter,
问题
为何必须在cmp2中显式指定string类型才能使排序生效?
解答
问题的核心在于向量的实际类型和泛型lambda的参数推导逻辑:
- 向量类型的推导:代码中
vector vec2 = {"sam", "zach", "adam", "peter"};在C++17及以后的自动类型推导规则下,会被推导为vector<const char*>——因为字符串字面量本质是const char*类型的指针,指向字符串在内存中的存储地址。 - 泛型lambda的参数推导:泛型lambda
cmp的auto参数会被推导为const char*,此时s1 < s2比较的是两个指针的内存地址,而非字符串的字典序。由于字符串字面量的内存地址顺序和它们的内容顺序无关,std::sort相当于使用了无效的比较规则,最终呈现“未排序”的结果。 - 显式指定
string的作用:cmp2中把参数指定为const string&时,传递的const char*元素会触发隐式类型转换,自动转为std::string对象,此时s1 < s2比较的是字符串的实际内容,因此能正确按字典序排序。
如果将向量显式声明为vector<string> vec2 = {"sam", "zach", "adam", "peter"};,泛型lambda的auto会被推导为string,此时cmp也能实现正确排序。
内容的提问来源于stack exchange,提问作者SandeshK3112
相关产品推荐
相关产品推荐

