2011-01-25 85 views
2

是否有一种简单的方法来创建指向向量元素的向量指针?通过参考从C++中获取向量指针向量

+3

用于什么?在任何情况下,你现在拥有的都是坏的:你得到了指向函数局部变量`v`的元素的指针;你回来后,这些指针就会晃动。您应该将该参数作为参考。 – GManNickG 2011-01-25 10:59:00

+2

给出的示例将产生一个指向该对象的指针向量,该对象在该函数退出后不存在。我假设你想要原型是'std :: vector fn(std :: vector &v)',即传递源矢量的引用,而不是将被销毁的副本。 – pmdj 2011-01-25 10:59:39

+0

该代码创建悬挂指针,并且很容易在大多数系统上崩溃或行为异常,因为`v`及其所有元素都在`fn`剩下时解除分配。 – Philipp 2011-01-25 11:02:41

回答

1

作为@Benoit建议,存储这些指针是一个坏主意。但是,如果你真的做到这一点,你可以使用std::transform这样的:

所有的
template<class T> 
struct Address 
{ 
    T* operator()(T& t) const 
    { 
     return &t; 
    } 
}; 


template<class T> 
vector<T*> fn(vector<T>& v) 
{ 
    vector<T*> r; 
    transform(v.begin(), v.end(), back_inserter(r), Address<T>()); 
    return r; 
} 


int main(void) 
{ 
    vector<int> a; 
    a.push_back(0); 
    fn(a); 
} 
6

我看不出有什么理由你需要这样做传入向量:

即不是更加容易的下面

std::vector<T*> fn(std::vector<T> &v) 
{ 
    std::vector<T*> r; 

    for (int i = 0; i < v.size(); i++) 
    { 
    r.push_back(&v[i]); 
    } 

    return r; 
} 

编辑。如果您增长v您的指针可能会失效;和r[i]只是&v[i]的别名。

如果你确实需要通过指针(我们仍然不明白为什么),你可以通过&v[0]和矢量的大小。鉴于std::vector的所有实现都必须保证向量中的元素连续存储在内存中,因此可以从第一个元素的地址和向量的大小中推导出所有地址。

1

没有标准的库函数来做到这一点。

std::vector<T*> pv(v.size()); 
for (size_t i=0; i<v.size(); ++i) 
    pv[i] = &v[i]; 

如果您不使用C++ 0x lambdas,可能是此循环的最短表达式。

1

你可以做线沿线的东西:

template <typename T> 
T* mk_ptr(T& t) { 
    return &t; 
} 

template <typename T> 
std::vector<T*> fn(std::vector<T>& v) { 
    std::vector<T*> r; 
    std::transform(v.begin(), v.end(), std::back_inserter(r), mk_ptr); 
    return r; 
} 

但人们想知道关于这个的动机......有是有原因的迭代器。没有人保证这些指针将保持有效。

1

首先,你必须找到一个正确的方式。您的代码(编辑:v通过值传递的原始代码)是错误的并导致未定义的行为。取决于应用程序,您通常需要pointer container或存储smart pointers的普通容器。