2012-01-31 5 views
2

이것은 이상한 질문 일 수 있습니다. 그러나 유형의 모든 값을 어떻게 멋지게 반복합니까? 특히 unsigned short과 같은 표준 적분 유형. 정상적인 for 루프 구조는 어려움을 나타냅니다 : 모든 값이 유효하기 때문에 루프를 종료하기 위해 사용할 조건.모든 값 위로 반복

물론 작업을 완료하는 데는 여러 가지 방법이 있습니다. 마지막 값을 종료하고 루프 이후를 처리하십시오. 카운트하려면 더 큰 int를 사용하십시오. 질문은 더 우아한 방법이 있는가? 내가 걱정

#include <limits> 
int i = std::numeric_limits<int>::min(); 
while(true) { 
    if(i == std::numeric_limits<int>::max()) 
     break; 
    ... 
    i++; 
}; 
+0

무언가를 무력화하려는 것 같습니다. 그래도 64 비트 정수로 시도하지 마십시오 ... – Mysticial

답변

2

당신은 당신이 할 수있는 매우 솔루션을 원하는 경우 :

for(auto x : everyvalue<short>()) { 
    std::cout << x << '\n'; 
} 

everyvalue은 다음과 같습니다 그렇지 않으면 간단한 break 것이 바람직 할 것이다

#include <limits> 
template<typename T> 
struct everyvalue { 
    struct iter { 
    T x; 
    bool flag; 
    inline iter operator++() { 
     if(x == std::numeric_limits<T>::max()) 
     flag = true; 
     else 
     ++x; 
     return *this; 
    } 
    inline T operator*() { return x;} 
    inline bool operator!=(iter& i) {return flag != i.flag;} 
    // note: missing some iterator requirements, still should work 
    }; 
    inline iter begin() { return iter{std::numeric_limits<T>::min(),0}; } 
    inline iter end() { return iter{std::numeric_limits<T>::max(),1}; } 
}; 

합니다.

+1

나는이 답변에 큰 녹색 진드기를 줄 예정입니다. 최종 결과는 우아하고 일반화되었습니다. 모든 추악한 것들은 한 번만하고, 올바르게 끝내고, 숨겨져 있습니다. 이것은 C++을 사용해야하는 방식의 큰 부분입니다 (제 의견으로는). 다른 대답들 중 일부는 성능상의 이점이있을 수 있지만 그게 내가했던 것만은 아닙니다. – wxffles

0

당신은 더 큰 유형을 사용할 수 있습니다 이 아주 똑같은 문제에 대해 한번 생각해보십시오. 그리고 이것은 제가 생각할 수있는 최선의 것입니다 :

unsigned char c = 0; 
do 
{ 
    printf("%d ", (int)c); //or whatever 
} while (++c != 0); 

do..while 구문이 유용한 매우 드문 경우 중 하나입니다.

기술적으로는 값의 줄 바꿈에 의존하기 때문에 부호없는 유형에만 유효합니다.

+0

'i <= i! = [...]'? 그것은 단지''<= [...]'이 될 의도였습니까? – quasiverse

+0

예 - 복사/붙여 넣기 오류! 결정된. –

+1

+1 물론'unsigned long'을 가정하면'unsigned short'보다 더 큽니다. 내가 아는 구현에 있지만, 나는 그것이 보장되지 않는다고 지적하고 있습니다. –

3
#include <limits> 
int i = std::numeric_limits<int>::min(); 
do { 
    ... 
    if(i == std::numeric_limits<int>::max()) 
     break; 
    i++; 
} while(true); 

이 대조적이다 :

+2

난 downvoting 아니지만 서명 된 정수 오버플로 정의되지 않은 동작입니다. (부호가있는 정수 오버플로의 예제는 http://stackoverflow.com/q/7682477을 참조하십시오. –

+0

큰 편집을하지 않아도됩니다. –

3

:에 변환하는 대한() 문에

unsigned long i; 
for (i = std::numeric_limits<unsigned short>::min(); 
    i <= std::numeric_limits<unsigned short>::max(); 
    i++) 
0

저는 최근에 bool에 관해서 같은 질문을했습니다 : How to write a `for` loop over bool values (false and true). 거기에서 답을 찾을 수 있습니다. 그런 다음 모든 for 값을 반복하는 for 루프가 조건을 한 번 더 평가해야하므로 모든 경우를 적절하게 구분하기 위해 추가 형식 (더 큰 형식, 두 번째 변수 등)으로 추가 값이 필요하다는 것을 알았습니다. 그리고 do-while 루프는 별개의 값과 동일한 수의 비교가 필요하기 때문에이 경우에 작동합니다.

1

당신은 당신이 과거 증가하지 않도록 당신이 최대에 도달했습니다 말을 당신이 플래그와 함께 증가하는 값을 결합 할 수 있습니다 :

for (char i (std::numeric_limits<char>::min()), j (1); 
     i != std::numeric_limits<char>::max() || j--; 
     i += j) 
    std::cout << (int) i << '\n'; 

을하지만, '정교한'보다는 같이 단지 우아한 '깨끗한 단순한 선들'.