在std::array<unique_ptr<int>>中使用std::binary_search编译报错的解决办法
在std::array<std::unique_ptr>上使用std::binary_search的编译错误解决
问题代码
#include <array> #include <memory> #include <algorithm> int main() { std::array<std::unique_ptr<int>, 3> a = {std::make_unique<int>(1), std::make_unique<int>(2), std::make_unique<int>(5)}; auto t = std::binary_search(a.begin(), a.end(), 5, [] (std::unique_ptr<int> x, std::unique_ptr<int> y) { return x.get() < y.get(); }); return 0; }
编译错误分析
第一个错误(传入int 5时)
Severity Code Description Project File Line Suppression State Details Error C2664 'bool thng_already::<lambda_1>::operator ()(std::unique_ptr<int,std::default_delete<int>>,std::unique_ptr<int,std::default_delete<int>>) const': cannot convert argument 1 from 'const _Ty' to 'std::unique_ptr<int,std::default_delete<int>>' with [ _Ty=int ] Proj C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\algorithm 7028
错误核心:std::binary_search会将容器元素(std::unique_ptr<int>)和目标值(int 5)传入比较器,但你的lambda要求两个参数都是std::unique_ptr<int>,类型不匹配导致转换失败。
第二个错误(传入std::make_unique<int>(5)时)
Severity Code Description Project File Line Suppression State Details Error C2280 'std::unique_ptr<int,std::default_delete<int>>::unique_ptr(const std::unique_ptr<int,std::default_delete<int>> &)': attempting to reference a deleted function Proj C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\algorithm 7028
错误核心:std::unique_ptr是独占所有权的智能指针,拷贝构造函数已被删除。你的lambda使用值传递参数(std::unique_ptr<int> x),会尝试拷贝传入的unique_ptr,触发删除的拷贝构造函数,导致编译失败。
另外,原代码的比较逻辑(x.get() < y.get())是比较指针的内存地址,而非指针指向的整数值,这不符合查找值为5的元素的需求;且容器未按指向的值排序,std::binary_search本身要求目标范围是已排序的,否则无法正确工作。
解决方案
关键修正点
- 使用const引用传递参数:避免拷贝
unique_ptr,绕过其删除的拷贝构造函数。 - 兼容参数类型:让比较器支持
unique_ptr<int>和int的双向比较(std::binary_search会同时做元素<目标值和目标值<元素的判断)。 - 修正比较逻辑:比较指针指向的整数值,而非指针地址。
- 先排序容器:确保数组按指向的值排序,满足
std::binary_search的前置条件。
正确代码示例
#include <array> #include <memory> #include <algorithm> #include <type_traits> int main() { std::array<std::unique_ptr<int>, 3> a = { std::make_unique<int>(1), std::make_unique<int>(2), std::make_unique<int>(5) }; // 定义通用比较器:自动适配unique_ptr和int类型的比较 auto cmp = [](const auto& lhs, const auto& rhs) { auto get_value = [](const auto& val) { if constexpr (std::is_same_v<std::decay_t<decltype(val)>, int>) { return val; } else { return *val; } }; return get_value(lhs) < get_value(rhs); }; // 按指向的整数值排序数组 std::sort(a.begin(), a.end(), cmp); // 使用binary_search查找值为5的元素 auto found = std::binary_search(a.begin(), a.end(), 5, cmp); // 可选:用lower_bound获取目标元素的迭代器 if (found) { auto it = std::lower_bound(a.begin(), a.end(), 5, cmp); if (it != a.end() && **it == 5) { // 成功找到目标元素 } } return 0; }
简化版比较器(C++17及以上)
如果不需要通用类型适配,也可以直接写一个简洁版本:
auto cmp = [](const auto& a, const auto& b) { return (std::is_same_v<std::decay_t<decltype(a)>, int> ? a : *a) < (std::is_same_v<std::decay_t<decltype(b)>, int> ? b : *b); };
内容的提问来源于stack exchange,提问作者AnthonyML
相关产品推荐
相关产品推荐

