Как получить определенный элемент в списке, учитывая позицию? - PullRequest
84 голосов
/ 20 апреля 2011

Итак, у меня есть список:

list<Object> myList;
myList.push_back(Object myObject);

Я не уверен, но уверен, что это будет "0-й" элемент в массиве.Могу ли я использовать какую-либо функцию, которая будет возвращать «myObject»?

Object copy = myList.find_element(0);

?

Ответы [ 4 ]

119 голосов
/ 20 апреля 2011

Если вам часто требуется доступ к N-му элементу последовательности, std::list, который реализован в виде двусвязного списка, вероятно, не является правильным выбором. std::vector или std::deque, вероятно, будет лучше.

Тем не менее, вы можете получить итератор для N-го элемента, используя std::advance:

std::list<Object> l;
// add elements to list 'l'...

unsigned N = /* index of the element you want to retrieve */;
if (l.size() > N)
{
    std::list<Object>::iterator it = l.begin();
    std::advance(it, N);
    // 'it' points to the element at index 'N'
}

Для контейнера, который не обеспечивает произвольный доступ, например std::list, std::advance вызывает operator++ на итераторе N раз. В качестве альтернативы, если это предусмотрено в реализации стандартной библиотеки, вы можете позвонить std::next:

if (l.size() > N)
{
    std::list<Object>::iterator it = std::next(l.begin(), N);
}

std::next эффективно переносит вызов на std::advance, облегчая продвижение итератора N раз с меньшим количеством строк кода и меньшим количеством изменяемых переменных. std::next был добавлен в C ++ 11.

30 голосов
/ 20 апреля 2011

std::list не предоставляет функции для получения элемента с указанным индексом. Вы можете попытаться получить его, написав некоторый код, который я бы не рекомендовал, потому что это было бы неэффективно, если вам часто приходится это делать.

Что вам нужно: std::vector. Используйте это как:

std::vector<Object> objects;
objects.push_back(myObject);

Object const & x = objects[0];    //index isn't checked
Object const & y = objects.at(0); //index is checked 
6 голосов
/ 11 апреля 2013
std::list<Object> l; 
std::list<Object>::iterator ptr;
int i;

for( i = 0 , ptr = l.begin() ; i < N && ptr != l.end() ; i++ , ptr++ );

if( ptr == l.end() ) {
    // list too short  
} else {
    // 'ptr' points to N-th element of list
}
2 голосов
/ 27 июня 2018

Возможно, не самый эффективный способ.Но вы можете преобразовать список в вектор.

#include <list>
#include <vector>

list<Object> myList;

vector<Object> myVector(myList.begin(), myList.end());

Затем получить доступ к вектору, используя оператор [x].

auto x = MyVector[0];

Вы можете поместить это в вспомогательную функцию:

#include <memory>
#include <vector>
#include <list>

template<class T>
shared_ptr<vector<T>> 
ListToVector(list<T> List) {
shared_ptr<vector<T>> Vector {
        new vector<string>(List.begin(), List.end()) }
return Vector;
}

Затем используйте вспомогательную функцию следующим образом:

auto MyVector = ListToVector(Object);
auto x = MyVector[0];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...