2011-08-03 2 views
7

지도를 반복 할 때 ++ 또는 it ++?

std::map를 반복하는 방법을 보여주는 예제는 다음과 같습니다.

MapType::const_iterator end = data.end(); 
for (MapType::const_iterator it = data.begin(); it != end; ++it) 

it++ 대신 ++it을 사용합니다. 왜 어떤 이유가 있습니까? 대신 it++를 사용하면 문제가 발생할 수 있습니까?

+0

[this] [1]을 (를) 보시기 바랍니다. [1] : http://stackoverflow.com/questions/24853/c-what-is-the-difference-between-i-and-i – sergio

+5

만약 시간의 길이에 대한 C++에서 사용하면 코드 ,'++는 효율을 크게 올릴 것입니다. 당신의 코드에는 없지만, 처음에는'++ '를하지 않은 이유를 사람들에게 설명하는 데 시간을 보냈습니다. 아주 조금이라도 중요하지 않기 때문에 논쟁을 불러 일으키지 않는 방법으로 할 수도 있습니다. –

+0

@Dennis : * 많이 * 중요하지 않으며 측정 할 수없는 경우가 많지만 긴밀한 루프에서는 차이가 날 수 있습니다. –

답변

10

테스트에 퍼팅, 나는 세 개의 소스 파일을 만든 : g++ -S -O3로 컴파일 후

#include <map> 

struct Foo { int a; double b; char c; }; 

typedef std::map<int, Foo> FMap; 

### File 1 only ### 

void Set(FMap & m, const Foo & f) 
{ 
    for (FMap::iterator it = m.begin(), end = m.end(); it != end; ++it) 
    it->second = f; 
} 

### File 2 only ### 

void Set(FMap & m, const Foo & f) 
{ 
    for (FMap::iterator it = m.begin(); it != m.end(); ++it) 
    it->second = f; 
} 

### File 3 only ### 

void Set(FMap & m, const Foo & f) 
{ 
    for (FMap::iterator it = m.begin(); it != m.end(); it++) 
    it->second = f; 
} 

### end ### 

을, GCC 4.6.1, 내가 찾아 해당 버전 2와 3 생산 동일 조립 및 버전 1 다릅니다 하나의 명령으로 만, cmpl %eax, %esicmpl %esi, %eax.

그래서 선택하고 자신의 스타일에 맞는 것을 사용하십시오. 접두어 증가 ++it은 요구 사항을 가장 정확하게 표현하기 때문에 아마도 가장 좋을지 모르지만 그에 대해 신경 쓸 필요는 없습니다.

+1

최적의 최적화 된 디스플레이가 있지만, 이는 충분히 간단하고 인라인 된'연산자 ++ '에서만 작동 할 수 있습니다. g ++이'std :: map'을 위해 그것을 할 수 있다는 것을 알았습니다. –

+1

@Christopher : 예, 여러분이 의미하는 바로는 항상'++ it '을 사용해야합니다. 나는 방금 두 개의 광고 광고 된 포인트 (끝을 끌어 올리고 접두어 증가분을 사용)의 진정한 영향에 대한 몇 가지 어려운 비교를 제공하는 것 같았습니다. –

20

it++은 이전 반복기의 복사본을 반환합니다. 이 반복자는 사용되지 않기 때문에 이것은 낭비입니다. ++it은 증분 된 반복기에 대한 참조를 반환하여 복사본을 피합니다.

자세한 내용은 Question 13.15을 참조하십시오.

+4

거의 문제가되지 않습니다. 이 문제는 순전히 스타일의 문제입니다. –

+1

@Dark - 사용되지 않기 때문에 컴파일러는이를 알아 차리고 복사본을 최적화합니다. –

+2

나는 그것을 알고있다. 분명히 컴파일러는 그렇게 할 필요는 없습니다. –

7

사전 증가 연산자와 사후 증가 연산자를 사용하는 경우 약간의 performance advantage이 있습니다. 반복자를 사용하여 루프를 설정, 당신은 사전에 단위를 사용하도록 선택해야 : 당신이 두 사업자는 일반적으로 implemented.The 선행 증가는 매우 간단합니다 것이 얼마나 생각하면

for (list<string>::const_iterator it = tokens.begin(); 
    it != tokens.end(); 
    ++it) { // Don't use it++ 
    ... 
} 

이유는 빛에 온다. 당신이 볼 수 있듯이, 게시물을

class MyInteger { 
private: 
    int m_nValue; 

public: 
    MyInteger(int i) { 
     m_nValue = i; 
    } 

    // Pre-increment 
    const MyInteger &operator++() { 
     ++m_nValue; 
     return *this; 
    } 

    // Post-increment 
    MyInteger operator++(int) { 
     MyInteger clone = *this; // Copy operation 1 
     ++m_nValue; 
     return clone; // Copy operation 2 
    } 
} 

그러나, 작업에 후행 증가 위해서는, 먼저, 개체의 복사본을 원본 개체의 실제 증가량을 한 후 사본을 반환해야 증분 구현에는 두 가지 추가 복사 작업이 필요합니다. 문제의 물체가 부피가 크다면 이것은 상당히 비쌀 수 있습니다. 그렇지만, 일부 컴파일러는 최적화를 통해 단일 복사 연산을 제거 할만큼 똑똑 할 수 있습니다. 요점은 후행 증가는 일반적으로 사전 증가보다 많은 작업을 필요로하므로 따라서 "++"를 반복 자보다 앞에 놓는 것이 익숙해지는 것이 현명한 방법입니다.

(1) 링크 된 웹 사이트에 대한 크레디트.

6

논리적 인 관점에서 - 동일하고 아무런 의미가 없습니다. 여기.

프리 픽스가 사용되는 이유는 더 빠르기 때문에 반복자를 변경하고 값을 반환하는 반면 후위는 임시 객체를 생성하고 현재 반복기를 증가시킨 다음 임시 객체를 반환합니다. 증가). 아무도이 임시 객체 (반환 값)를 여기에서 감시하지 않으므로 동일합니다 (논리적으로).

컴파일러가이를 최적화 할 가능성이 매우 높습니다.


는 또한 - 사실이 전혀 어떤 유형에 대해 다음과 같이 가정된다. 그러나 그것은 단지 있어야합니다. 누구든지 operator++ - 접미사와 접두어를 오버로드 할 수 있기 때문에 부작용과 다른 동작이 발생할 수 있습니다.

음, 이것은 끔찍한 일이지만 여전히 가능합니다.

+0

참으로 끔찍한 일입니다. 데이터를 스트림에 넣기 위해 이동 연산자를 남용하는 것과 같은 것입니까? ;-) (SCNR) –

+0

글쎄요, 좋은 지적입니다. 어쨌든 당신은 궁극적으로 어떤 이유로 든 복사하기에 너무 비싸고 최적화 될 수없는 커스텀 반복자를 처리 할 수 ​​있습니다. '+++ ')보다는 ('C++') 사용하는 것이 좋은 습관 일 뿐이다. –

+0

@Kerrek SB - 정확히 :) 항상 '++ bla_bla'를 선호합니다. 사용하면 괜찮습니다. –

1

아무런 문제가 발생하지 않지만 ++it을 사용하는 것이 더 정확합니다.

operator++(type x,int){ 
    type tmp=x; //need copy 
    ++x; 
    return tmp; 
} 

컴파일러는 그 중 일부를 최적화 할 수 있지만 반드시 어렵다 : 작은 타입으로 정말 ++i 또는 i++하지만 "큰"클래스를 사용하는 것이 중요하지 않습니다.

1

다른 답변으로 말하면, 문맥에서 작동하지 않는 한 ++를 선호합니다. 작은 유형의 컨테이너를 반복하는 경우에는 컴파일러가이를 최적화하면 차이가 거의 없지만 큰 유형의 컨테이너의 경우 복사본 작성 비용을 절약 할 수 있으므로 차이를 만들 수 있습니다.

사실 상황에 따라 유형이 충분히 작아서 걱정할 필요가 없을 수도 있습니다. 하지만 나중에 팀원 중 누군가가 컨테이너의 내용을 중요한 부분으로 변경할 수 있습니다. 또한 좋은 습관을 얻는 것이 낫다는 점을 알고 나면 포스트 증가가 더 좋습니다.

관련 문제