std::ranges::copy不能直接拷贝到空容器,需预先分配空间或使用std::back_inserter;参数为迭代器范围,要求目标可写且满足weakly_incrementable;拷贝到std::string需字符类型严格匹配。

std::ranges::copy 不能直接拷贝到空容器
它不会自动扩容目标容器,必须确保目标空间足够。常见错误是直接对空 std::vector 调用 std::ranges::copy,结果写入越界或静默失败(取决于迭代器类型和编译器)。
正确做法是预先分配空间,或改用能增长的迭代器:
- 用
vec.resize(n)预留大小,再传vec.begin() - 用
std::back_inserter(vec)—— 这是唯一安全适配空容器的方式 - 注意
std::back_inserter返回的是输出迭代器,不支持随机访问,性能略低但语义明确
std::ranges::copy 和 std::copy 的参数顺序一致
都是 (source_first, source_last, dest_first),不是“源-目标”对象顺序。容易误写成 copy(vec, dest) 这类伪代码,实际必须传迭代器范围。
典型用法示例:
立即学习“C++免费学习笔记(深入)”;
std::vector<int> src = {1,2,3};
std::vector<int> dst(3); // 预分配
std::ranges::copy(src.begin(), src.end(), dst.begin());
若用 std::back_inserter:
std::vector<int> dst; std::ranges::copy(src, std::back_inserter(dst)); // 这里 src 可以是 range,支持简写
std::ranges::copy 要求目标迭代器可写且满足 weakly_incrementable
这意味着不能传 const 容器的 begin(),也不能传 std::array 的 cbegin()。编译错误通常提示类似 no match for 'operator=' 或 weakly_incrementable 不满足。
常见踩坑点:
-
const std::vector<int> v{1,2,3}; std::ranges::copy(v, ...)→ 编译失败 -
std::array<int, 3> a; std::ranges::copy(src, a.begin())→ OK;但a.cbegin()不行 - 自定义类型需重载
operator=,且迭代器类型要满足 C++20 输出迭代器概念
拷贝到 std::string 需注意字符类型匹配
std::ranges::copy 对 std::string 的目标要求严格:源值类型必须能隐式转换为 char(或 unsigned char 等),否则编译失败。比如从 std::vector<int> 拷贝到 std::string 就不行,哪怕数值在 0–127 范围内。
可行场景:
-
std::ranges::copy("hello", str.begin())→ OK(字面量转const char*) -
std::ranges::copy(chars_vec, std::back_inserter(str)),其中chars_vec是std::vector<char> - 想把数字转成字符写入?得先手动转换:
std::ranges::transform(nums, std::back_inserter(str), [](int n) { return static_cast<char>(n); })
std::ranges::copy 的契约很薄:它只管写,不管内存。是否 resize、是否类型兼容、是否线程安全,全由调用者负责。


















