2016-07-01 5 views
0

У меня есть вектор std::vector<MyClass> myclass_vec(10) с 10 инициализированными объектами MyClass. Теперь я хотел бы перебрать этот вектор и сохранить ссылку на каждый объект MyClass в другом векторе std::vector<MyClass> myclass_vec_refs. Причина, по которой я хотел бы хранить ссылки, заключается в том, что мне не нужно копировать объекты и, очевидно, ссылаться на тот же объект, что и на myclass_vec.Как хранить ссылки на объекты из одного вектора в другом векторе в C++?

По какой-то причине это не работает как аспектированное. Должен ли я объявлять std::vector<&MyClass> myclass_vec_refs так?

Поскольку я просматривал другие вопросы, заданные здесь, я читал около std::unique_ptr. Если я изменю std::vector<std::unique_ptr<MyClass>> myclass_vec(10), то я бы не смог получить ссылку или указатель в myclass_vec_refs, так как они объявлены уникальными. Поправьте меня, если я ошибаюсь.

Другой подход заключался в использовании std::shared_ptr. Поскольку он содержит контрольный счетчик, я мог бы указать myclass_vec_refs на объекты в myclass_vec, но я читал, что это вводит довольно некоторые накладные расходы, а share_ptr следует использовать только в качестве последнего средства.

Я также не знаю, ссылаются ли ссылки, как я пытаюсь. Что произойдет, если объект в myclass_vec удален? Является ли вектор myclass_vec_refs измененным размером на -1, поскольку объект больше не существует или он просто указывает на плохую память?

Возможно ли emplace_back ссылку в каталоге myclass_vec_refs? Поскольку это создает объект на месте, я предполагаю, что это не работает, и можно использовать только push_back?

+0

Почему не просто хранить итератор в другой вектор? – NathanOliver

+3

Почему не хранить указатели вместо выделенного объекта? –

+3

Почему бы вам не хранить индексы? –

ответ

1

Вы не может сделать вектор ссылки. Почему?

Ссылка должна ссылаться на фактический объект в любое время, а векторы по дизайну должны иметь возможность создавать «пустые» объекты (то есть конструктор по умолчанию) динамически для вас.

Вы можете создать вектор указателей.

Если другой вектор изменен каким-либо образом, ваши указатели станут недействительными. Если это проблема, используйте карту или комплект.

+1

Это правда, что у вас не может быть векторов ссылок, но ваши рассуждения ошибочны. Вектор не требует, чтобы объект был по умолчанию конструктивным. Хотя некоторые функции-члены вектора do (по крайней мере, 'resize (size_type count)' и 'vector (size_type count)' таковы), но вам не нужно использовать эти функции для использования вектора. – user2079303

+1

@ user2079303: На самом деле 'vector' этого не требует. Или более точно, 'vector' * alone * не накладывает требования к копированию/перемещению. Именно методы 'vector' фактически вставляют/удаляют элементы, которые налагают это требование. Основная вещь 'vector ' требует от 'T' стирается через функцию' destroy' распределителя. А для 'std :: allocator' ссылок нет. –

+0

@NicolBolas ой, я совершил ту же ошибку, что и исправляю в первую очередь. – user2079303

1

Как ответил здесь: Strange Template Deduction

Хитрость заключается в том, чтобы использовать std::reference_wrapper<>

#include <algorithm> 
#include <iostream> 
#include <vector> 

template<typename container_ty_, class Comp> 
auto where(container_ty_& V, Comp&& comp) 
{ 
    using value_type = typename container_ty_::value_type; 
    using reference = 
    std::conditional_t< 
     std::is_const<container_ty_>::value, 
     std::reference_wrapper<const value_type>, 
     std::reference_wrapper<value_type> 
    >; 

    std::vector<reference> cursor; 

    for(auto& VAL : V) 
     if(comp(VAL)) 
      cursor.push_back(VAL); 

    return cursor; 
} 

int main(int argc, char** argv) { 
    std::vector<int> tVect = {0, 5, 2, 1, 7, 9}; 

    //Why must std::vector<int> be passed... 
    auto vec = where(tVect, [](const int& V) -> bool { return V > 5; }); 

    std::for_each(vec.begin(), vec.end(), [] (int& v) { std::cout << v++ << std::endl; }); 
    std::cout << std::endl; 
    std::for_each(tVect.begin(), tVect.end(), [](const int& v) { std::cout << v << std::endl; }); 
} 
+0

@Sean M .: Это реальный ответ на все ваши вопросы! – Roland

 Смежные вопросы

  • Нет связанных вопросов^_^