12

AdaPascal、および他の多くの言語は、整数をサブタイプする方法である範囲をサポートしています。範囲は、値 (最初) から別の値 (最後) までの範囲の符号付き整数値です。OOP で同じことを行うクラスを実装するのは簡単ですが、この機能をネイティブにサポートすることで、コンパイラが追加の静的チェックを実行できるようになると思います。

範囲内で定義された変数が実行時に「オーバーフロー」しないことを静的に検証することは不可能であることはわかっています。より一般的なソリューションを提供する Design by Contract アプローチ (Eiffel) と Spec# (C# Contracts )について考えます

C++、C#、および Java でコンパイル時に少なくとも静的な範囲外の割り当てをチェックする、より簡単なソリューションはありますか? ある種のstatic-assert ?

編集:「範囲」はさまざまな目的に使用できることを理解しています:

  1. イテレータ
  2. 列挙子
  3. 整数サブタイプ

前者は C* 言語で簡単にマッピングできるため、後者に焦点を当てます。音楽の音量のような値の閉じたセット、つまり 1 から 100 までの範囲について考えます。値を増減したいと思います。次のような静的オーバーフローの場合にコンパイルエラーが発生するようにしたいと思います。

volume=rangeInt(0,100);
volume=101;  // compile error!
volume=getIntFromInput(); // possible runtime exception

ありがとう。

4

11 に答える 11

3

範囲は、その範囲で簡潔に何かを実行できる場合に最も役立ちます。それは閉鎖を意味します。少なくとも Java と C++ の場合、その範囲で何をするかを定義する内部クラスを定義する必要があるため、範囲型は反復子と比較して面倒です。

于 2009-01-29T16:05:47.730 に答える
3

部分範囲型は、実際にはあまり役に立ちません。固定長の配列を割り当てることはあまりありません。また、固定サイズの整数を使用する理由もありません。通常、固定サイズの配列が列挙として機能していることがわかりますが、それに対するより良い (「より重い」) 解決策があります。

サブレンジ型も型システムを複雑にします。定数を固定するよりも、変数間に制約を導入する方がはるかに便利です。

(適切な言語では、整数は任意のサイズにする必要があることに注意してください。)

于 2009-01-29T12:04:49.323 に答える
2

C++ の場合、制約値変数のライブラリが現在実装されており、boost ライブラリで提案される予定です: http://student.agh.edu.pl/~kawulak/constrained_value/index.html

于 2009-01-29T16:29:43.970 に答える
1

これは古い質問ですが、更新したかっただけです。Java 自体には範囲がありませんが、関数が本当に必要な場合は、 IntRangeを含む多くの範囲クラスを持つCommons Langを使用できます。

IntRange ir = new IntRange(1, 10);

奇妙なことに、これは Commons Math には存在しません。私は受け入れられた答えに部分的に同意しますが、特にテストケースでは、範囲が役に立たないとは思いません。

于 2010-07-26T21:00:49.050 に答える
1

C++ では、テンプレートを使用してそのような型を実装できます。これを行うライブラリが既にいくつかあると思います。ただし、ほとんどの場合、利点が小さすぎて、追加された複雑さとコンパイル速度のペナルティを正当化できないと思います。

静的アサートに関しては、既に存在します。Boost には がありBOOST_STATIC_ASSERT、Windows では、Microsoft の ATL ライブラリが同様のものを定義していると思います。

boost::type_traitsと boost::mpl は、おそらくこのようなものを実装する際の親友です。

于 2009-01-29T16:18:39.373 に答える
1

Tom Hawtin の回答 (これには同意します) に追加しますが、C++ の場合、範囲の存在はそれらがチェックされることを意味するものではありません。とにかく範囲チェックされていません。C# と Java の場合、決定はパフォーマンスに基づいていたと思います。範囲をチェックすると、負担がかかり、コンパイラが複雑になります。

範囲は主にデバッグ フェーズで役立つことに注意してください。範囲違反は、(理論的には) 製品コードで発生することはありません。したがって、範囲チェックは、言語自体の内部ではなく、リリース ビルドを作成するときに削除できる (はずの) 事前条件および事後条件で実装する方が適切です。

于 2009-01-30T21:45:09.807 に答える
1

自分で作成できる柔軟性は、言語に組み込まれているよりも優れています。たとえば、範囲外の値に対して例外をスローする代わりに、飽和演算が必要な場合はどうすればよいでしょうか? いえ

MyRange<0,100> volume = 99;
volume += 10; // results in volume==100
于 2009-01-30T21:26:57.083 に答える
0

JSR-305 は範囲のサポートを提供しますが、これが Java の一部になるかどうかはわかりません。

于 2009-01-30T20:37:09.493 に答える