C ++ 20でが導入されましたstd::common_reference
。その目的は何ですか?誰かがそれを使用する例を挙げられますか?
C ++ 20でが導入されましたstd::common_reference
。その目的は何ですか?誰かがそれを使用する例を挙げられますか?
回答:
common_reference
プロキシイテレータに対応するSTLのイテレータの概念化を思い付いた私の努力から生まれました。
STLでは、反復子には2つのタイプの関連する特別な関心がreference
ありvalue_type
ます。およびです。前者はイテレータのの戻り値の型でoperator*
あり、value_type
はシーケンスの要素の(非const、非参照)型です。
一般的なアルゴリズムでは、多くの場合、次のようなことを行う必要があります。
value_type tmp = *it;
...したがって、これら2つのタイプの間には何らかの関係があるはずです。非プロキシイテレータの場合、関係は単純reference
です。常にでvalue_type
、オプションでconstと参照が修飾されています。概念を定義するための初期の試みでInputIterator
は、式*it
がに変換可能であることが必要であり、const value_type &
興味深い興味深い反復子にはそれで十分です。
C ++ 20のイテレータをこれよりも強力にしたかったのです。たとえばzip_iterator
、ロックステップで2つのシーケンスを反復するの必要性を検討してください。を間接参照すると、2つのイテレータの型のzip_iterator
一時的なものを取得します。したがって、a とaには、次のタイプが関連付けられます。pair
reference
zip
vector<int>
vector<double>
zip
イテレータのreference
:pair<int &, double &>
zip
イテレータのvalue_type
:pair<int, double>
ご覧のとおり、これらの2つのタイプは、トップレベルのcv-およびref修飾を追加するだけでは互いに関連していません。しかし、2つのタイプを任意に異なるものにすると、間違っているように感じます。明らかに、ここには何らかの関係があります。しかし、その関係は何であり、イテレータで動作する一般的なアルゴリズムは2つのタイプについて何を安全に想定できるでしょうか。
C ++ 20での答えはのためということである任意の有効なイテレータ型、プロキシまたはない、種類reference &&
とvalue_type &
共有共通の基準を。つまり、一部のイテレータit
にはCR
、次のような整形式になるタイプがあります。
void foo(CR) // CR is the common reference for iterator I
{}
void algo( I it, iter_value_t<I> val )
{
foo(val); // OK, lvalue to value_type convertible to CR
foo(*it); // OK, reference convertible to CR
}
CR
共通のリファレンスです。すべてのアルゴリズムは、このタイプが存在するという事実に依存することができ、std::common_reference
それを計算するために使用できます。
つまり、それがcommon_reference
C ++ 20のSTLで果たす役割です。一般に、一般的なアルゴリズムやプロキシイテレータを作成していない限り、無視しても問題ありません。これは、イテレータが契約上の義務を確実に満たすことを保証する裏側にあります。
編集:OPも例を求めました。これは少し不自然ですが、C ++ 20で、何もわからないr
タイプのランダムアクセス範囲が与えられ、その範囲にアクセスしR
たいとsort
します。
さらに、何らかの理由で、のような単相比較関数を使用したいとしますstd::less<T>
。(たぶん、あなたは型消去範囲をしました、そして、あなたはまた、比較関数消去を入力して、それを渡す必要がvirtual
?再度、ストレッチ。)すべきである何T
になりますかstd::less<T>
?そのためにcommon_reference
は、、またはiter_common_reference_t
それに関して実装されているヘルパーを使用します。
using CR = std::iter_common_reference_t<std::ranges::iterator_t<R>>;
std::ranges::sort(r, std::less<CR>{});
これは、範囲r
にプロキシイテレータがある場合でも機能することが保証されています。
pair<T&,U&>
およびpair<T,U>&
共通の基準を持っているでしょうし、それは単純になりますpair<T&,U&>
。ただし、の場合std::pair
、からpair<T,U>&
への変換はありませんpair<T&,U&>
が、そのような変換は原則的には有効です。(ちなみに、これzip
がC ++ 20でのビューがない理由です。)
pair
その目的のために特別に設計されたタイプではなく、zipイテレータがを使用しなければならない理由がありますか?、必要に応じて適切な暗黙の変換を使用して?
std::pair
。適切な変換を備えた適切なペアのような型が実行され、range-v3はそのようなペアのような型を定義します。委員会に関して、LEWGは、標準ライブラリに、std::pair
それが規範的であろうとなかろうとほとんどないタイプを標準ライブラリに追加するという考えを嫌いましたstd::pair
。
tuple
、、pair
、- - 。とで要素にアクセスできるこの素晴らしい機能があります。構造化されたバインディングは、すべてではなく、s での作業の厄介な部分に役立ちます。tomato
to
MAH
to
pair
.first
.second
tuple