使用不同类型调用std::upper_bound编译失败,求原因及解决
问题解决:std::upper_bound跨类型调用编译失败
问题场景
使用自定义比较器跨类型调用std::upper_bound时编译报错,但相同逻辑的std::lower_bound可正常编译运行。
问题代码
#include <deque> struct MyData { int a{-1}; static struct { bool operator() (const MyData &left, const int &right) const { return left.a < right; } } CompareA; }; void do_stuff() { std::deque<MyData> myDeque { MyData{.a = 1}, MyData{.a = 2}, MyData{.a = 3}, MyData{.a = 4}, }; auto lower = std::lower_bound(myDeque.begin(), myDeque.end(), 2, MyData::CompareA); auto upper = std::upper_bound(myDeque.begin(), myDeque.end(), 3, MyData::CompareA); }
错误信息
在Xcode(clang)环境下,std::upper_bound编译时触发以下通用错误提示(实际问题并非__nat本身):
struct __nat { #ifndef _LIBCPP_CXX03_LANG __nat() = delete; __nat(const __nat&) = delete; __nat& operator=(const __nat&) = delete; ~__nat() = delete; '~__nat' has been explicitly marked deleted here #endif };
问题根源
std::lower_bound的核心逻辑是寻找第一个不满足comp(element, value)的元素,仅需比较器支持(MyData, int)的参数顺序,因此可正常工作。std::upper_bound需要寻找第一个满足comp(value, element)的元素,这要求比较器必须支持反向参数顺序(int, MyData),当前比较器仅实现了单向逻辑,导致模板推导失败,触发libc++的通用错误提示。- 你观察到的移动语义差异是libc++内部实现细节,并非问题根源。
解决方案
给比较器添加反向参数的重载,使其支持双向比较:
struct MyData { int a{-1}; static struct { // 用于lower_bound的正向比较 bool operator() (const MyData &left, const int &right) const { return left.a < right; } // 用于upper_bound的反向比较 bool operator() (const int &left, const MyData &right) const { return left < right.a; } } CompareA; };
修改后,std::upper_bound可正常推导并调用对应比较逻辑,编译通过。
内容的提问来源于stack exchange,提问作者Karl
相关产品推荐
相关产品推荐

