是否有从std::vector<T>
转换为std::vector<T*>
或std::vector<T&>
的快捷方式?
基本上我想替换:
std::vector<T> source;
std::vector<T*> target;
for(auto it = source.begin(); it != source.end(); it++)
{
target.push_back(&(*it));
}
只有一行。
提供一些上下文:我有一组函数可以在std::vector<Polygon>
上进行计算,有些函数需要std::vector<Polygon*>
。所以我需要来回转换几次,因为这些函数的接口不应该改变。
答案 0 :(得分:10)
虽然你所描述的内容听起来很奇怪(没有上下文),但使用std::transform
你可以在一行代码中进行实际的复制/转换:
transform(source.begin(), source.end(), target.begin(), getPointer);
鉴于target
有足够的空间容纳所有数据(可以用std::vector::resize
实现,例如。),并给出这个一元运算符:
template<typename T> T* getPointer(T& t) { return &t; }
答案 1 :(得分:6)
如果你有c ++ 0x,下面的代码可以解决这个问题(lambda需要c ++ 0x):
template <typename T>
std::vector<T*> convertFrom(std::vector<T>& source)
{
std::vector<T*> target(source.size());
std::transform(source.begin(), source.end(), target.begin(), [](T& t) { return &t; });
return target;
}
一方面注意:确保在最后一次使用目标矢量之前未清除源矢量,因为它是实际对象的所有者。目标向量只包含指针。
答案 2 :(得分:1)
我之前回答的另一个想法是使用boost iterators。
由于它完全不同,我认为我会将其作为新回复发布:
首先使用boost::transform_iterator
:
template<typename T> T* getPointer(T& t) { return &t; }
boost::transform_iterator<T* (*)(T&), std::vector<T>::iterator> begin(source.begin(), getPointer), end(source.end(), getPointer);
std::vector<T*> target(begin, end);
或者从source
向量构建target
向量(如果该方向也适合您),您可以使用boost::indirect_iterator
:
boost::indirect_iterator<std::vector<T*>::iterator> begin(target.begin()), end(target.end());
std::vector<T> source(begin, end);
它可能不那么漂亮,但它很有效。