You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

std::sort排序小写字符串vector时出现与空字符串比较的疑问

问题复现代码
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

int main(int argc, char const *argv[])
{
  std::vector<std::string> lst{"cat", "dog", "dogs", "chicken", "chickens", "cats", "dogs"};
  std::sort(lst.begin(), lst.end(), [](const auto &lhs, const auto &rhs)
  {
    int i = 0;
    int n = lhs.size();
    int m = rhs.size();
    std::cout << n << " " << m << std::endl;

    while(i < n && i < m && lhs.at(i) == rhs.at(i))
    {
      ++i;
    }

    if(i == n && i == m) return true; // same exact word
    else if(i == n || i == m) return lhs.size() < rhs.size(); 

    return lhs.at(i) < rhs.at(i);
  });
}
问题原因
  1. 自定义比较函数不符合std::sort要求的严格弱序约束,触发未定义行为。
    严格弱序要求比较函数comp(a,b)必须满足:如果a和b逻辑相等,那么comp(a,b)和comp(b,a)都必须返回false。你代码中当两个字符串完全相等时,返回值为true,直接违反了该约束,会导致std::sort内部逻辑完全错乱。
  2. 空字符串的来源是被移动后的原列表元素。std::sort排序过程中会移动元素调整位置,当比较逻辑异常时,可能会访问已经被移动走的std::string对象。C++标准规定被移动后的std::string处于有效但未指定的状态,绝大多数标准库实现都会将被移动后的字符串置为空,这就是你看到长度为0的字符串的原因,并非出现了不在原列表中的新元素。
修复方案

仅需要修改相等场景的返回值即可,相等元素不满足小于关系,返回false:

if(i == n && i == m) return false;

修改后比较函数符合严格弱序要求,未定义行为消失,不会再出现空字符串的异常。

内容的提问来源于stack exchange,提问作者user5965026

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:42:00