Получить вектор указателей из вектора в C ++ - PullRequest
2 голосов
/ 25 января 2011

Есть ли простой способ создания вектора указателей на элементы вектора?

т.е. проще чем ниже

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;
}

РЕДАКТИРОВАТЬ: Входящий вектор по ссылке

Ответы [ 5 ]

6 голосов
/ 25 января 2011

Я не вижу причин, почему вам нужно это сделать.Если вы вырастите v, ваши указатели могут стать недействительными;и r[i] - это просто псевдонимы для &v[i].

Если вам действительно нужно передать указатели (мы до сих пор не поняли, почему), вы можете просто передать &v[0] и размер вектора.Учитывая, что вся реализация std::vector должна гарантировать, что элементы в векторе хранятся непрерывно в памяти, вы можете вывести все адреса из адреса первого элемента и размера вектора.

1 голос
/ 25 января 2011

Прежде всего, вы должны найти правильный способ. Ваш код ( edit: исходный код, в котором v передается по значению, то есть) неверен и приводит к неопределенному поведению. В зависимости от приложения обычно требуется контейнер указателя или обычный контейнер, в котором хранятся интеллектуальные указатели .

1 голос
/ 25 января 2011

Как предположил @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);
}
1 голос
/ 25 января 2011

Вы могли бы сделать что-то вроде:

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 голос
/ 25 января 2011

Для этого нет стандартной библиотечной функции.

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

, вероятно, является кратчайшим выражением этого цикла, если вы не используете C ++ 0x лямбда-выражения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...