使用空std::vector的begin()和end()是否属于定义良好的行为?
问题:空std::vector作为源调用insert时,使用begin()和end()是否定义良好?
我通过std::vector::insert将一个vector复制到另一个vector,但不确定当源vector为空时,传入它的begin()和end()是否在所有情况下都是定义良好的。我看到文档里提到:“若allocator_traits::construct不支持元素构造的合适参数,或指定了无效位置或范围,则会导致未定义行为。”,因此产生了疑问。
我的代码示例如下:
#include <vector> #include <stdio.h> void printbytes(char* bytes, size_t len) { if(len == 0) return; for(size_t i=0; i<len; i++) { printf("%x ", *(bytes+i) & 0xff); } printf("\n"); } int main() { std::vector<char> target = {'h','e','l','l','o'}; std::vector<char> source = {'w','o','r','l','d'}; // 确定是定义良好的 target.insert(target.end(), source.begin(), source.end()); printbytes(target.data(), target.size()); // 这是否定义良好? source.clear(); target.insert(target.end(), source.begin(), source.end()); printbytes(target.data(), target.size()); // 那这个呢? std::vector<char> boo; boo.insert(boo.end(), source.begin(), source.end()); printbytes(boo.data(), boo.size()); }
回答
完全定义良好,不会触发未定义行为。
核心原因:
空容器的begin()和end()是有效且相等的迭代器,它们构成的范围[begin(), end())是一个合法的空范围。C++标准明确规定,对于insert的范围版本,当输入范围为空(即first == last)时,函数不会执行任何插入操作,直接返回,整个过程完全符合标准要求。
对文档描述的澄清:
你看到的“指定了无效位置或范围”指的是以下这类情况:
- 迭代器来自不同容器,或者迭代器指向的容器已被销毁/失效;
- 范围的顺序错误(比如
first在last之后,且容器不是反向迭代器类型); - 使用了已失效的迭代器(比如容器扩容后未更新的迭代器)。
而空容器的begin()和end()属于有效的迭代器,它们构成的空范围完全符合要求,不属于“无效范围”的范畴。
对应你的代码场景:
- 第一个调用(源非空):正常插入元素,行为明确。
- 第二个调用(
source.clear()后):source.begin() == source.end(),insert不会向target添加任何元素,target保持原有状态,操作合法。 - 第三个调用(空容器
boo插入空范围):同样不会插入任何元素,boo始终为空,操作完全定义良好。
内容的提问来源于stack exchange,提问作者Timothy John Laird
相关产品推荐
相关产品推荐

