C ++の間隔、パヌト4無限倧たで

最埌の郚分では、むンクリメンタヌIterableの抂念に぀いお説明し、暙準間隔に固有の倚くの問題を解決する方法を瀺したした。 次に、このコンセプトを拡匵しお、無限のむンタヌバルプログラミングをより安党で効率的なビゞネスにしたす。



免責事項 この蚘事のアむデアは、以前のアむデアよりも投機的です。 議論ができお嬉しいです。



以前の投皿で話した解決枈みの問題に加えお、さらに2぀ありたす。 これは



  1. 䞀郚のSTLアルゎリズムは無限の間隔で機胜したせん
  2. 無限たたはおそらく無限の間隔は、difference_typeオヌバヌフロヌに぀ながりたす


無限むテレヌタヌ



iota_range-ある倀から始たり、氞久に続く無限の敎数の範囲。 これは、゜ヌトされた前方スペヌスです。 以䞋は、゜ヌトされたたっすぐな間隔で機胜するバむナリ怜玢アルゎリズムであり、機胜したせん。 分割によっお無限を埁服するこずはできたせん良いフレヌズが刀明したした。



無限の間隔を受信したずきに壊れないようにSTLアルゎリズムを修正するこずは可胜ですか 珟圚の圢匏では、いいえ-むテレヌタの䞀郚が無限の間隔を瀺すずいうコンパむル段階で情報を䌝えるこずは䞍可胜です。 これに぀いお考えおみおください。次のコヌドは確実に機胜したす。



//  : iota_range<bigint> rng; auto i = std::lower_bound(rng.begin(), std::next(rng.begin(), 10), 5);
      
      







しかし、これは氞遠に機胜したす



 //   «» :'-( iota_range<bigint> rng; auto i = std::lower_bound(rng.begin(), rng.end(), 5);
      
      







rng.beginがrng.endず同じタむプの堎合、2぀の呌び出しは同じlower_boundむンスタンスを返したす。 関数は、氞久に機胜するかどうかを刀断できたせん。 ただし、シグナルむテレヌタを別のタむプにするこずができる堎合は、コンパむル段階でこのチェックを実行できたす。

DenotesInfiniteSequenceず呌ばれる型関数メタ関数があり、それが型のペアBeginType、EndTypeを取り、シヌケンスが無限かどうかを刀断するずしたす。 BeginTypeずEndTypeが同じ堎合、DenotesInfiniteSequenceはfalseを返す必芁があるこずを既に決定しおいたす。これは、これをどのような方法でも怜蚌できないためです。 しかし、それらが異なる堎合-EndTypeのタむプがunreachable_sentinelたたはそのようなものになるずするず、コンパむル段階でシヌケンスが無限であるこずがわかりたす。



無限の間隔



䞀郚の間隔は、定矩䞊、同じタむプの開始反埩子ず終了反埩子を持぀こずもあり、無限になりたす。



 //    class zeros : public range_facade<zeros> { friend range_core_access; struct impl { bool sentinel; int current() const { return 0; } void next() {} bool equal(impl that) const { return sentinel == that.sentinel; } }; // begin()  end()   range_facade //  begin_impl  end_impl.      impl begin_impl() const { return {false}; } impl end_impl() const { return {true}; } }; //    Range CONCEPT_ASSERT(Range<zeros>()); int main() { //  for_each(zeros(), [](int i) {/*...*/}); }
      
      







このような゚ラヌをすぐにキャッチしたいのですが、明らかに、バむナリ関数DenotesInfiniteSequenceはこれに察凊できたせん。 れロの堎合、BeginTypeタむプずEndTypeタむプは同じになるため、DenotesInfiniteSequenceはfalseを返したす。



したがっお、区間型を受け入れるIsInfinite型の単項関数を䜜成する必芁がありたす。



 //   ,   Iterable  template<typename Iterable> struct is_infinite : std::integral_constant<bool, true-or-false> {};
      
      







FiniteIterableの抂念を定矩するために䜿甚できたす。



 //    Concept Lite template<typename T> concept bool FiniteIterable = Iterable<T> && !is_infinite<T>::value;
      
      







各FiniteIterableは反埩可胜です。 改良の䞊列階局が芳察されたす。



画像



たた、これらの抂念はすべお、Rangeずの類掚により、コヌドで定矩する必芁はありたせん。 有限性はIterable階局に盎亀しおおり、個別に問い合わせるこずができたす。



しかし、なぜInfiniteIterableではなくFiniteIterableなのでしょうか アルゎリズムずその芁件がすべおです。 間隔匕数を無限にする必芁があるアルゎリズムはありたせん。 したがっお、InfiniteIterableを蚘述できおも意味がありたせん。 しかし、lower_boundのようなアルゎリズムは、間隔が有限であるこずを望みたす。 これずFiniteIterableから。



これは、すべおの反埩子がデフォルトでFiniteIterableをモデル化し、その型が䜕らかの圢で無限であるこずを孊習する必芁があるこずを意味したす。 どうやっお is_infiniteを特殊化するこずができたす。 幞いなこずに、むンクリメンタヌずむンタヌバルを䜜成するツヌルはオプションのIsInfiniteパラメヌタヌを受け入れるため、これは簡単です。 zeroesクラスは次のようになりたす。



 //   class zeros : public range_facade<zeros, true> { // ... IsInfinite ...................^^^^ // ...  ,   ... }; // zeros –  Range,    Finite CONCEPT_ASSERT(Range<zeros>()); CONCEPT_ASSERT(!FiniteIterable<zeros>());
      
      







FiniteIterableコンセプトを远加するこずにより、有限性を必芁ずするアルゎリズムに、コンパむル段階でこれを怜蚌する機䌚を䞎えたす。



おそらく無限の間隔



次に、間隔をカテゎリに分割する必芁がありたす。 理論的には、無限たたは有限のどちらかです。そうではありたせんか いや istreamを利甚しおください。 それは有限かもしれないし、そうでないかもしれない。 通垞、フロヌは停止したすが、時には...



状況は耇雑です。 istreamのアルゎリズムぞの転送を犁止する必芁があるのは、それが無限である可胜性があるためだけですか



カりント䞍可



無限の間隔では、このような困難がありたす。すべおのむテレヌタずすべおのむンクリメンタには、それらに関連付けられたdifference_typeがありたす。 アレクサンダヌ・ステパノフはこれに぀いお曞いおいたす



DistanceTypeは、その型に有効な埌続アプリケヌションのシヌケンスを枬定するのに十分な倧きさの敎数型を返したす。




あらゆるサむズの無限サむズが必芁であるこずがわかりたした。 この問題の解決策はありたすか



  1. C ++では、bigintが必芁です-粟床が無限の型党䜓です。 他の蚀語ではそうです。 C ++はラむブラリを䜜成するのに最適な蚀語であり、ラむブラリはそれを求めおいるだけです。 そのようなタむプがあった堎合、それはdifference_typeずしお取られたす。
  2. 無限間隔では、safe_intをdifference_typeずしお䜿甚できたす。 safe_intはintのように動䜜したすが、無限を衚すこずができたす。 混んでいたせん。 difference_typeのオヌバヌフロヌに関する2぀の最も難しい問題は、未定矩の動䜜ず、䜕が間違っおいたかを事実を䌝えるこずができないこずです。 safe_intを䜿甚するず、䞍確実性を回避し、埌で䜕が起きるかを回避できたす。
  3. オヌバヌフロヌ時に䟋倖をスロヌする代替のsafe_int実装が提案される堎合がありたす。
  4. たた、ラむブラリがdifference_typeを䜿甚する堎所を確認し、別のタむプがそこで䜿甚されるようにナヌザヌに指定させるこずもできたす。 たずえば、距離蚈算アルゎリズムAPIは、間隔ずオプションの初期倀を取る堎合がありたす。 デフォルトでは、difference_type {0}で動䜜したすが、bigintを枡した堎合は、異なる、より遅いが、より安党な方法で動䜜したす。
  5. 問題を無芖できたす。 そしお、オヌバヌフロヌを気にする人は、カりントダりン間隔アダプタヌhttps://github.com/ericniebler/range-v3/blob/master/include/range/v3/view/counted.hppを䜿甚しお確認できたす。その繰り返しは、difference_typeがオヌバヌフロヌする前に停止したす。
  6. 私には起こらなかった䜕か。




もちろん、アルゎリズムの動䜜を遅くするものすべおが奜きではないので、std :: ptrdiff_tはデフォルトでdifference_typeのたたにしおおくこずができたす。 さらに、ナヌザヌがオヌバヌフロヌを心配する堎合に別のdifference_typeを蚭定できるように、むンタヌバルむンタヌフェむスを蚭蚈する必芁がありたす。 したがっお、オプション4ず5が奜きです。特定の制限を持぀bigintやsafe_intのような他のラむブラリタむプは、䜿甚できるずいいでしょう。



結果ず次に䜕をすべきか



おそらく、前の投皿を読んでいる間、あなたは過床に楜芳的でしたすべおがうたくいき始めおいるようで、今あなたは混乱しおいたす。 しかし、私が始めた堎所ず比范しお、私たちは順調に進歩しおいるように思えたす。 むテレヌタのペアを䜿甚しお、間隔に関する5぀の問題を説明したした。 むンクリメンタヌの新しい抂念はそれらのうち3぀を解決し、4番目の問題無限間隔はこの抂念を改善するこずで理論的に解決できたす。 たた、5番目オヌバヌフロヌを凊理するためのオプションがいく぀かありたす。 少なくずも開始されたした。



私のアむデアをC ++暙準化委員䌚に䌝えたいず思う人もいたす。 もちろん。 蚀語の抂念のサポヌトが埗られるず、異なる名前空間で動䜜する可胜性のある抂念化されたバヌゞョンのSTLが必芁になりたす。



それたでの間、SG9Rangesメヌリングリストhttp://www.open-std.org/mailman/listinfo/rangesでこの問題を議論したす。 この議論のある問題は、新しいアむデアを生み出す可胜性がありたす。 興味のある方は、ディスカッションに参加するこずをお勧めしたす。



著者は圌のアむデアを委員䌚に持ち蟌み、珟圚それらの実装に取り​​組んでいたす。

その他のサむクル蚘事

C ++の間隔、パヌト1区切り蚘号付きの間隔

C ++の間隔、パヌト2無限の間隔

C ++の間隔、パヌト3むンクリメントの導入反埩可胜




All Articles