2014-11-30 3 views
0

내가 반복하는 목록이 있다고 가정합니다. 내가 뭔가 흥미로운 것을 발견하면 나는 사본을 먹고 싶어하고 그 시점에서 뭔가를 할 :목록 및 관련 반복기 복사

std::list<int> a; 
for(auto i = a.begin(); i != a.end(); ++i) 
{ 
    if(is_interesting(*i)) 
    { 
     std::list<int> b = a; // take a copy 
     do_something(b, i); // :(
    } 
} 

은 물론이 반복자 ia하지 b 참조하기 때문에 작동하지 않을. b에서 i이 참조하는 동일한 위치를 나타내는 반복자 j을 얻으려면 a? 당신은 당신의 루프 조건으로 카운터를 증가, 대신의 오프셋 재 계산하여이를 최적화 할 수

std::list<int> b = a; 
std::list<int>::iterator j = b.begin(); 
std::advance(j, std::distance(a.begin(), i)); 

:

+0

당신은'std :: distance'와'std :: advance'로 할 수 있습니다. 그러나 이것은 나에게 꽤 어색한 것처럼 보입니다. 무작위 액세스 컨테이너에서는 좋지 않습니다. 왜 전체 목록을 복사해야합니까? 그리고 왜 루프 안에서? –

+0

http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem –

+0

@LightnessRacesinOrbit 그게 효과가 있지만 불필요하게 느릴 것이라고 상상해 봅니다. 내 목록의 수정 된 버전을 목록의 목록에 추가하고 싶습니다. – wxffles

답변

1

여기에 한 가지 방법입니다. 물론 list에 대한 distanceadvance 함수는 목록을 트래버스합니다.

의견에서 언급했듯이이 작업을 수행해야 할 필요가있는 것은 코드에 대한 더 높은 수준의 설계 가능성이 있음을 의미합니다. 목록을 복사해야하는 이유를 알지 못하면 목록의 일부만 복사하면됩니다. 여기에 다음 전체 목록이 필요 할 경우

std::list<int> b2(i, a.end()); 

는 옵션입니다 (이 첫 번째 옵션보다 더 복잡성을 가지고 있는지 확실하지 않습니다!) :

std::list<int> b(a.begin(), i); 
std::list<int> b2(i, a.end()); 
std::list<int>::iterator j = b2.begin(); 
b.splice(b.end(), b2); // moves all of b2's elements into b 

접합은 O (1)의 list에 대한 물론, 그것은 단지 몇 가지 포인터를 twiddling이기 때문에. 스플 라이스는 객체가 다른 목록으로 이동 한 경우에도 반복자를 유지하도록 보장됩니다.

+0

나는 마지막 예제가 의미론, 복잡성, 그리고 - 충분히 가깝다 - 실제 런타임이라는 관점에서 첫 번째 예제와 같다고 생각한다. –