2012-01-31 6 views
2

これは奇妙な質問かもしれませんが、どのようにして1つの型のすべての値をうまくループしますか?特に、unsigned shortのような標準的な整数型。通常のforループ構成では、すべての値が有効であるため、ループを終了するためにどの条件を使用するのが難しいかがわかります。すべての値をループする

もちろん、ジョブを実行するにはいくつかの方法があります。最後の値を終了し、ループの後でそれを処理します。カウントするにはより大きな整数を使用します。質問は、よりエレガントな方法があるということですか?私は心配

#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!= [...]'?それはちょうど 'i <= [...]'の意味ですか? – quasiverse

+0

Yup - コピー/貼り付けエラー!一定。 –

+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ループが条件をもう一度評価する必要があるので、すべてのケースを適切に区別するために余分な値(より大きな型、2番目の変数など)を必要とすることを認識しました。また、このケースでは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'; 

をしかし、「洗練された」のではなく内のみとエレガント'単純な線をきれいにする'。

関連する問題