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

使用const string&构造函数搭配模板化std::set find触发段错误

段错误触发原因分析

这个问题的根本原因是无限递归调用导致的栈溢出,整个触发链路如下:

  1. 编译时默认使用的C标准版本低于C17,标准库未提供std::string和std::string_view直接比较的运算符重载。
  2. 你的Person类构造函数未加explicit修饰,支持从const std::string&隐式构造Person实例。
  3. 调用set::find(string_view)时,透明比较器std::less<>执行string_view和Person的比较,匹配到你定义的全局运算符bool operator<(string_view s,const Person& p)。
  4. 该运算符内部执行return s < p.name:其中s是string_view,p.name是std::string,由于标准库没有对应比较重载,编译器会尝试隐式类型转换:用p.name(std::string)隐式构造临时Person对象,匹配你写的operator<(string_view, const Person&)。
  5. 这就形成了无限递归:operator<(string_view, Person)内部又调用自身,很快耗尽栈空间,最终触发段错误,和你提供的gdb栈访问非法的错误信息完全吻合。

为什么替换为string_view构造函数就正常?

当构造函数改为接受string_view时,执行return s < p.name时如果需要隐式转换:
会将p.name转string_view,再构造临时Person,然后调用两个Person之间的比较运算符bool operator<(const Person& o)const,直接比较两个Person的name成员,不会触发递归,因此程序正常运行。

修复方案

  • 最佳方案:给Person的构造函数添加explicit修饰,禁止无意义的隐式类型转换,从根源避免这类问题,也符合C++编码规范。
  • 编译时指定C17或更高版本(如g添加-std=c++17参数,VS设置C标准为C17+),启用标准库中string和string_view的直接比较运算符,不会触发隐式转换。
  • 补充std::string和std::string_view的比较逻辑,避免编译器触发隐式转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:27:03