多分、
template <typename T> void closed_range(T begin, const T end)
if (begin <= end) {
do {
// do something
} while (begin != end && (++begin, true));
}
}
呪い、私の最初の試みは間違っていました、そして上記の修正は私が望んでいたほどきれいではありません. どうですか:
template <typename T> bool advance(T &value) { ++value; return true; }
template <typename T> void closed_range(T first, const T last)
if (first <= last) {
do {
// do something
} while (first != last && advance(first));
}
}
2 つのパラメーターを取るstd::advance
ため、T が整数型でなくてもあいまいさはありません。std::advance
したがって、何らかの理由でそれらの閉じた範囲が必要な場合、テンプレートはたとえばランダム アクセス イテレータでも機能します。
または、集合論について少し考えてみませんか?明らかに、閉じた範囲でループを 1 つだけ記述している場合、これは非常にやり過ぎですが、多くのことを実行したい場合は、ループ コードが適切になります。endof
効率については不明です: 非常にタイトなループでは、呼び出しが巻き上げられていることを確認したい場合があります:
#include <limits>
#include <iostream>
template <typename T>
struct omega {
T val;
bool isInfinite;
operator T() { return val; }
explicit omega(const T &v) : val(v), isInfinite(false) { }
omega &operator++() {
(val == std::numeric_limits<T>::max()) ? isInfinite = true : ++val;
return *this;
}
};
template <typename T>
bool operator==(const omega<T> &lhs, const omega<T> &rhs) {
if (lhs.isInfinite) return rhs.isInfinite;
return (!rhs.isInfinite) && lhs.val == rhs.val;
}
template <typename T>
bool operator!=(const omega<T> &lhs, const omega<T> &rhs) {
return !(lhs == rhs);
}
template <typename T>
omega<T> endof(T val) {
omega<T> e(val);
return ++e;
}
template <typename T>
void closed_range(T first, T last) {
for (omega<T> i(first); i != endof(last); ++i) {
// do something
std::cout << i << "\n";
}
}
int main() {
closed_range((short)32765, std::numeric_limits<short>::max());
closed_range((unsigned short)65533, std::numeric_limits<unsigned short>::max());
closed_range(1, 0);
}
出力:
32765
32766
32767
65533
65534
65535
omega<T>
オブジェクトで他の演算子を使用する場合は少し注意してください。私はデモンストレーションのために絶対最小値のみを実装し、omega<T>
暗黙的に に変換しT
ます。そのため、オメガ オブジェクトの「無限性」を捨てる可能性のある式を記述できることがわかります。算術演算子の完全なセットを宣言する (必ずしも定義する必要はない) ことで、これを修正できます。または isInfinite が true の場合、変換で例外をスローします。または、コンストラクターが明示的であるため、誤って結果をオメガに戻すことができないという理由で心配する必要はありません。しかし、たとえば、omega<int>(2) < endof(2)
は真ですが、omega<int>(INT_MAX) < endof(INT_MAX)
偽です。