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

在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本身要求目标范围是已排序的,否则无法正确工作。

解决方案

关键修正点

  1. 使用const引用传递参数:避免拷贝unique_ptr,绕过其删除的拷贝构造函数。
  2. 兼容参数类型:让比较器支持unique_ptr<int>和int的双向比较(std::binary_search会同时做元素<目标值和目标值<元素的判断)。
  3. 修正比较逻辑:比较指针指向的整数值,而非指针地址。
  4. 先排序容器:确保数组按指向的值排序,满足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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:32:45