如何从double*数组初始化std::vector<double*>,替代循环实现?
首先得提一句,你原代码里有个小bug:myVector(dataCount, NULL);这行写法不对,因为myVector已经是类的成员变量了,不能像临时对象那样调用构造函数。而且就算改成myVector.assign(dataCount, nullptr);,后面又用push_back的话,会让vector里先有dataCount个空指针,再追加dataCount个目标指针,最后总元素数是两倍的dataCount,这肯定不是你想要的结果。
回到你的需求,不用for循环的话,有几种简洁的方式:
方法一:用std::iota(C++11及以上)
这是最简洁的方式,std::iota会自动把起始值依次递增填充到容器里,而指针的递增刚好对应数组元素的地址偏移,完美匹配你的需求:
#include <numeric> // 需要包含这个头文件 void MyClass(double* vectorData, size_t dataCount) { myVector.resize(dataCount); std::iota(myVector.begin(), myVector.end(), vectorData); // 后续逻辑... }
它会把vectorData、vectorData+1、...、vectorData+dataCount-1依次赋值给myVector的每个元素,完全替代原有的循环。
方法二:用std::generate_n(C++11及以上)
如果需要更灵活的生成逻辑(比如不是简单的地址递增),可以用std::generate_n搭配lambda表达式:
#include <algorithm> #include <iterator> // 用于back_inserter void MyClass(double* vectorData, size_t dataCount) { myVector.clear(); myVector.reserve(dataCount); // 预留空间避免频繁扩容 size_t idx = 0; std::generate_n(std::back_inserter(myVector), dataCount, [&]() { return vectorData + idx++; }); // 后续逻辑... }
这里的lambda表达式会逐个生成指向数组元素的指针,效果和原循环完全一致。
方法三:自定义迭代器(兼容C++03)
如果你的项目还在使用C++03,没法用lambda和std::iota,可以自己写一个简单的计数迭代器,配合vector的范围构造函数:
#include <iterator> // 用于std::iterator struct PointerIterator : std::iterator<std::input_iterator_tag, double*> { double* ptr; explicit PointerIterator(double* p) : ptr(p) {} double* operator*() const { return ptr; } PointerIterator& operator++() { ++ptr; return *this; } bool operator!=(const PointerIterator& other) const { return ptr != other.ptr; } }; // 然后在构造函数中使用: void MyClass(double* vectorData, size_t dataCount) { myVector = std::vector<double*>( PointerIterator(vectorData), PointerIterator(vectorData + dataCount) ); // 后续逻辑... }
这种方式直接通过迭代器范围初始化整个vector,完全不需要手动循环。
最后还要提醒一句:不管用哪种方法,都要确保vectorData指向的数组生命周期至少和myVector一样长,不然会出现野指针问题哦~
内容的提问来源于stack exchange,提问作者Robert

