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

如何通过C++20 Ranges View填充std::pmr::vector并传入内存资源?

用Ranges填充std::pmr::vector时传入内存资源的解决办法

几种可行的实现方式

  • 先构造容器再拷贝
    最稳妥的方式是先手动创建带指定内存资源的std::pmr::vector,再用ranges::copy把视图元素导入,不管是std::ranges还是ranges-v3都能正常运行:

    #include <ranges>
    #include <vector>
    #include <memory_resource>
    
    int main() {
        std::pmr::monotonic_buffer_resource mr;
        std::pmr::vector<int> numbers{&mr}; // 传入内存资源初始化容器
        std::ranges::copy(std::views::iota(0, 10), std::back_inserter(numbers));
    }
    
  • 自定义适配器(ranges-v3专属)
    如果你用的是ranges-v3,可以自己写个简易适配器,实现构造参数的转发:

    #include <ranges>
    #include <vector>
    #include <memory_resource>
    #include <range/v3/utility/functional.hpp>
    #include <range/v3/range/conversion.hpp>
    
    template <template <typename...> class C, typename... Args>
    auto to_with_args(Args&&... args) {
        return ranges::make_pipeable(ranges::detail::convert_to<C>{
            std::forward<Args>(args)...
        });
    }
    
    int main() {
        std::pmr::monotonic_buffer_resource mr;
        auto numbers = std::views::iota(0, 10) | to_with_args<std::pmr::vector<int>>(&mr);
    }
    

    这个写法直接复用了ranges-v3内部的转换逻辑,仅新增了参数转发的能力。

  • C++23原生支持(看编译器版本)
    若你使用支持C++23的编译器(如GCC 13+、Clang 16+),std::ranges的to已经支持传递容器构造参数,直接编写即可:

    #include <ranges>
    #include <vector>
    #include <memory_resource>
    
    int main() {
        std::pmr::monotonic_buffer_resource mr;
        auto numbers = std::views::iota(0, 10) | std::ranges::to<std::pmr::vector<int>>(&mr);
    }
    

关于是不是库的疏漏

C20的std::ranges里to确实不支持转发构造参数,这属于早期设计的局限性,而非疏漏——C20的to仅实现了最基础的容器转换功能,传递构造参数的特性是C++23标准才补充的。

至于ranges-v3,早期版本也有同样限制,你可以选择自己写适配器绕过,或者升级到新版本,部分新的ranges-v3版本已经支持带参数的to重载。

内容的提问来源于stack exchange,提问作者user4218502

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:57:25