0

0

c++23的std::ranges::to如何与自定义容器一起使用? (容器转换)

尼克

尼克

发布时间:2026-01-13 13:58:02

|

861人浏览过

|

来源于php中文网

原创

std::ranges::to 可与自定义容器配合使用,前提是容器满足 range 要求且提供 std::from_range 构造函数或迭代器区间/initializer_list 构造函数;否则因约束不满足而编译失败。

c++23的std::ranges::to如何与自定义容器一起使用? (容器转换)

直接说结论:std::ranges::to 可以与自定义容器配合使用,但前提是该容器满足 std::ranges::range 要求,并且提供符合标准的 iteratorsentinel 和(关键)**可推导的构造函数签名** —— 尤其是支持从 std::initializer_list 或一对迭代器构造。

为什么 std::ranges::to 有时对自定义容器“不生效”?

常见错误现象是编译失败,报错类似:

error: no matching function for call to 'to(...)'  
note: candidate template ignored: constraints not satisfied

根本原因不是容器没实现 begin/end,而是 std::ranges::to 内部依赖 std::container_from_range 的约束检查,它要求:

  • 容器类型 T 必须是 std::regular(可复制、可比较等)
  • T 必须能通过 T{std::from_range, r} 构造(C++23 新语法)
  • 或者存在 T{first, last} 构造函数(即支持迭代器区间构造)
  • 或存在 T{std::initializer_list} 构造函数(但仅限于输入范围可静态转为 std::initializer_list 的情况,实际限制很大)

如何让 MyContainer 支持 std::ranges::to?

最可靠、最通用的方式是显式添加「来自 range」的构造函数。C++23 引入了 std::from_range 标签类型,专用于此场景:

立即学习C++免费学习笔记(深入)”;

struct MyContainer {
    using value_type = int;
    // ... 其他成员(data_, size_ 等)
// ✅ 关键:支持 std::from_range + range 构造
templatezuojiankuohaophpcnstd::input_iterator I, std::sentinel_forzuojiankuohaophpcnIyoujiankuohaophpcn S>
MyContainer(std::from_range_t, I first, S last) {
    while (first != last) {
        push_back(*first++);
    }
}

// ✅ 也建议加上 initializer_list 版本(方便调试和小数据)
MyContainer(std::initializer_listzuojiankuohaophpcnvalue_typeyoujiankuohaophpcn il) 
    : MyContainer(std::from_range, il.begin(), il.end()) {}

};

MuleRun
MuleRun

全球首个AI Agent交易平台

下载

注意:std::from_range_tstd::ranges::from_range 的类型别名,必须用它作为第一个参数,否则 std::ranges::to 无法匹配。

实际调用时要注意什么?

使用方式很简洁,但有几点容易踩坑:

  • 必须显式指定容器模板参数,如 std::ranges::to(rng);不能依赖 CTAD,因为 to 是函数模板,不参与类模板实参推导
  • 如果 MyContainer 有多个构造函数(比如带 allocator 的),确保 std::from_range 版本不被重载解析歧义干扰 —— 建议加 explicit 或用 requires 约束
  • 性能上:std::ranges::to 不会做容量预估(除非你容器自己在构造中实现了 reserve),所以对大范围建议提前预留空间
  • 兼容性:GCC 13+ / Clang 16+ / MSVC 19.35+ 才完整支持 std::ranges::tostd::from_range

一个最小可运行示例

验证是否真的 work:

#include 
#include 
#include 

struct MyContainer { std::vector data_; explicit MyContainer(std::from_ranget, auto first, auto last) : data{first, last} {} // 直接委托给 vector 的区间构造

auto begin() { return data_.begin(); }
auto end() { return data_.end(); }

};

int main() { auto v = std::vector{1, 2, 3, 4, 5}; auto c = std::ranges::to(v); // ✅ 编译通过 for (int x : c.data_) std::cout

真正复杂的地方在于:自定义容器的迭代器类别(input_iterator 还是 random_access_iterator)会影响 std::ranges::to 内部是否尝试 size() 预分配 —— 但这个行为由标准库实现决定,你只能通过容器自己的构造函数控制实际开销。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

534

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

194

2025.08.29

交互式图表和动态图表教程汇总
交互式图表和动态图表教程汇总

本专题整合了交互式图表和动态图表的相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.01.13

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

1

2026.01.13

nginx部署php项目教程汇总
nginx部署php项目教程汇总

本专题整合了nginx部署php项目教程汇总,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

PHP 表单处理与文件上传安全实战
PHP 表单处理与文件上传安全实战

本专题聚焦 PHP 在表单处理与文件上传场景中的实战与安全问题,系统讲解表单数据获取与校验、XSS 与 CSRF 防护、文件类型与大小限制、上传目录安全配置、恶意文件识别以及常见安全漏洞的防范策略。通过贴近真实业务的案例,帮助学习者掌握 安全、规范地处理用户输入与文件上传的完整开发流程。

7

2026.01.13

PPT交互图表教程大全
PPT交互图表教程大全

本专题整合了PPT交互图表相关教程汇总,阅读专题下面的文章了解更多详细内容。

56

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQL 教程
SQL 教程

共61课时 | 3.4万人学习

10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号