如何通过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
相关产品推荐
相关产品推荐

