据我所知,只要您有合适的比较器,就应该可以将 upper_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);
}
lower_bound
编译得很好,但是 upper_bound
在 Xcode (clang) 上失败:
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
};
我猜这是某种包罗万象的错误?似乎没有任何方法可以解决实际问题。我可以看到模板化函数本身的唯一区别是
upper_bound
使用移动语义,而 lower_bound
不使用:
return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
对
return std::__upper_bound<_ClassicAlgPolicy>(
std::move(__first), std::move(__last), __value, std::move(__comp), std::__identity());
所以事实证明
lower_bound
和 upper_bound
需要以相反的顺序传递给比较器的参数。因此:
#include <deque>
struct MyData
{
int a{-1};
static struct
{
bool operator() (const MyData &left, const int &right) const
{
return left.a < right;
}
} CompareLower;
static struct
{
bool operator() (const int &left, const MyData &right) const
{
return left < right.a;
}
} CompareUpper;
};
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::CompareLower);
auto upper = std::upper_bound(myDeque.begin(), myDeque.end(), 3, MyData::CompareUpper);
}
比无用更糟糕的错误消息只是一个额外的好处。