从向量到指针向量的最短转换

时间:2011-07-29 07:32:27

标签: c++ stl

是否有从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*>。所以我需要来回转换几次,因为这些函数的接口不应该改变。

3 个答案:

答案 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);

它可能不那么漂亮,但它很有效。

相关问题