위치가 주어진 경우 목록에서 특정 요소를 얻는 방법은 무엇입니까?


92

그래서 목록이 있습니다.

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

확실하지는 않지만 이것이 배열의 "0 번째"요소가 될 것이라고 확신합니다. "myObject"를 반환 할 수있는 함수가 있습니까?

Object copy = myList.find_element(0);

?


8
배열이 없습니다-목록입니다. 정수로 인덱싱하려면 vector대신 사용하지 않는 이유는 무엇입니까?
Paul J. Lucas

2
항상 요소 0을 원하면 front().
Paul J. Lucas

나는이 테스트를하지 않은,하지만 난 myList.front () + NUM 여기서 일 것이라고 생각할 겁니다
세르게이하기 Fedorov

2
@SergueiFedorov : 아니오, 그렇지 않습니다
Algoman

답변:


129

시퀀스의 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::nextC ++ 11에 추가되었습니다.


18
랜덤 액세스의 부족으로 인해 연결된 목록을 검색하는 성능 저하를 지불하는 동안 벡터 또는 데크 중간에 데이터를 삽입하거나 제거해야하는 경우 훨씬 더 큰 성능 저하를 지불합니다. 질문에는 실제로 목적에 이상적인 컨테이너를 사용하고 있는지 결정하기에 충분한 정보가 포함되어 있지 않습니다.
tloach

1
그것의 가치를 사용할 때 있음을 지적 std::advance하거나 std::next, UB를 호출하기 쉽습니다. 경계 검사가 없습니다.
okovko

33

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 

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

3

가장 효율적인 방법은 아닐 수도 있습니다. 그러나 목록을 벡터로 변환 할 수 있습니다.

#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];
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.