如何为含std::string成员的结构体使用默认太空船运算符?
默认太空船运算符与std::string在Apple Clang 14下的兼容问题
你的代码逻辑本身没有问题,编译失败的核心原因是Apple Clang 14附带的libc标准库未实现std::string的C20太空船运算符(<=>)。而其他平台(如你提到的在线编译环境)使用的是更新的标准库实现,所以能正常编译通过。
具体原因
C20标准要求所有标准库容器类型必须支持<=>运算符,但不同厂商的标准库更新进度不一致。Apple Clang 14对应的libc版本中,std::string类还没有添加<=>的默认实现,这导致你尝试默认生成结构体的operator<=>时,编译器找不到成员c对应的太空船运算符,最终只能隐式删除这个默认生成的运算符,触发编译错误。
解决方法
1. 单独默认operator==(仅需相等判断场景)
如果你的需求只是实现相等比较,完全不需要依赖operator<=>。std::string的operator==早已被支持,直接默认结构体的相等运算符即可:
struct MyStruct { float a{}; int b{}; std::string c{}; MyEnum d{}; // 仅默认相等运算符,无需依赖<=> bool operator==(const MyStruct&) const = default; };
2. 手动实现operator<=>(需完整比较逻辑场景)
如果需要排序类的比较功能,可以手动实现operator<=>,用std::string::compare方法替代<=>的作用:
#include <compare> #include <string> enum class MyEnum { ZERO = 0, ONE = 1 }; struct MyStruct { float a{}; int b{}; std::string c{}; MyEnum d{}; bool operator==(const MyStruct&) const = default; auto operator<=>(const MyStruct& other) const { if (auto cmp = a <=> other.a; cmp != 0) return cmp; if (auto cmp = b <=> other.b; cmp != 0) return cmp; // 用compare方法模拟<=>的比较行为 auto str_cmp = c.compare(other.c); if (str_cmp != 0) { return str_cmp < 0 ? std::strong_ordering::less : std::strong_ordering::greater; } return d <=> other.d; } };
3. 升级编译器版本
更新到Xcode 15及以上版本,对应的Apple Clang版本会附带已实现std::string <=>的libc++,此时你的原代码就能正常编译。
内容的提问来源于stack exchange,提问作者rbv
相关产品推荐
相关产品推荐

