当以array+count为last参数时,vector<string>范围构造函数的工作原理
const char**转vector<string>的疑问 我正在研究如何将原生const char**转换为vector<string>,在Stack Overflow上找到了一个简洁的实现方法:
const char* array[] = {"cat", "cows", "crows"}; int count = 3; vector<string> stringVector(array, array + count);
我认为这使用了C++标准库中vector的范围构造函数:
template< class InputIt > vector( InputIt first, InputIt last, const Allocator& alloc = Allocator() );
但我有个疑问:array + count这种指针算术操作没有考虑中间每个字符串的长度,怎么就能指向最后一个字符串的下一个位置?如果需要考虑字符串长度,这一过程是如何、在哪里发生的?我原本以为如果仅传起始指针和字符串数量,底层会通过查找空终止符来处理,但这里看起来是直接的指针算术,array+count似乎没有足够信息定位到正确的结束位置,除非operator+对字符串有特殊处理。
解答
首先要明确:这里的array是**const char*类型的数组**,不是单个字符串的字符数组,两者的指针算术逻辑完全不同:
array + count的计算只和数组元素的类型大小有关:array的每个元素是const char*(32位系统占4字节,64位系统占8字节),所以array + count等价于(const char**)((char*)array + count * sizeof(const char*))——它直接跳过count个const char*元素,指向数组最后一个元素的下一个位置,和单个字符串的长度没有任何关系。处理字符串长度的环节是在
std::string的构造阶段:范围构造函数会遍历first到last之间的每个const char*指针,逐个调用std::string(const char*)构造函数,这个构造函数会自动通过空终止符\0计算字符串长度,完成内存分配和内容拷贝。你混淆了两种指针逻辑:遍历单个字符串的
const char*时需要依赖\0判断结束,但遍历存储字符串指针的const char**数组时,只需要知道数组的元素个数,因为每个元素都是独立的指针,指针算术只需要按元素类型的跨度计算即可。
内容的提问来源于stack exchange,提问作者CCJ

