透明なコンパレータとは何ですか? 質問する

透明なコンパレータとは何ですか? 質問する

C++14 では、連想コンテナが C++11 から変更されたようです – [associative.reqmts]/13 には次のように書かれています:

メンバー関数テンプレートfind、、、、は、型が存在しない限り、オーバーロード解決に参加しませcountん。lower_boundupper_boundequal_rangeCompare::is_transparent

コンパレータを「透明」にする目的は何ですか?

C++14 では次のようなライブラリ テンプレートも提供されます。

template <class T = void> struct less {
    constexpr bool operator()(const T& x, const T& y) const;
    typedef T first_argument_type;
    typedef T second_argument_type;
    typedef bool result_type;
};

template <> struct less<void> {
    template <class T, class U> auto operator()(T&& t, U&& u) const
    -> decltype(std::forward<T>(t) < std::forward<U>(u));
    typedef *unspecified* is_transparent;
};

例えばstd::set<T, std::less<T>>ない透明な比較器を持っていますが、std::set<T, std::less<>> だろう持っています。

これはどのような問題を解決しますか、また、標準コンテナの動作は変わりますか? たとえば、 のテンプレート パラメータはstd::set引き続き なのでKey, Compare = std::less<Key>, ...、デフォルト セットでは 、 などのメンバーは失われますfindcount?

ベストアンサー1

これは何の問題を解決するのか

見るディートマーの答えそしてremyabelの回答

これにより、標準コンテナの動作は変わりますか?

いいえ、デフォルトではそうではありません。

etc.の新しいメンバー関数テンプレートオーバーロードをfind使用すると、キーの型自体を使用する代わりに、コンテナのキーと比較できる型を使用できます。N3465この機能を追加するための根拠と詳細かつ慎重に書かれた提案を提供してくれた Joaquín Mª López Muñoz に感謝します。

ブリストル会議では、LWGは異種ルックアップ機能が有用かつ望ましいことに同意しましたが、Joaquínの提案がすべてのケースで安全であるとは確信できませんでした。N3465提案は、一部のプログラムで深刻な問題を引き起こす可能性があります(既存のコードへの影響セクション)。Joaquín は、異なるトレードオフを伴ういくつかの代替実装を含む更新されたドラフト提案を準備しました。これは、LWG が長所と短所を理解するのに非常に役立ちましたが、それらはすべて何らかの形で一部のプログラムを破壊するリスクがあったため、機能を追加することについてのコンセンサスは得られませんでした。私たちは、機能を無条件に追加することは安全ではないものの、デフォルトで無効にして「オプトイン」のみにすれば安全であると判断しました。

主な違いはN3657提案(これは私とSTLによる土壇場での修正であり、N3465その後、Joaquín による未発表の草案も作成され、is_transparent新しい機能にオプトインするために使用できるプロトコルとして型を追加することになりました。

「透過的なファンクタ」(つまり、型を定義するもの)を使用しない場合is_transparent、コンテナはこれまでと同じように動作し、それがデフォルトのままです。

std::less<>(C++14 の新機能) または別の「透過的なファンクタ」型を使用することを選択した場合、新しい機能が得られます。

std::less<>エイリアス テンプレートを使用すると簡単に使用できます。

template<typename T, typename Cmp = std::less<>, typename Alloc = std::allocator<T>>
  using set = std::set<T, Cmp, Alloc>;

名前はis_transparentSTLのN3421C++14 に「ダイヤモンド演算子」が追加されました。「透過的な関数」とは、任意の引数型 (同じである必要はありません) を受け入れ、それらの引数を別の演算子に転送する関数です。このような関数は、連想コンテナでの異種ルックアップに必要なものであるため、すべてのダイヤモンド演算子に型が追加され、連想コンテナで新しい機能を有効にする必要があることを示すタグ型is_transparentとして使用されました。技術的には、コンテナには「透過的な関数」は必要ありません。異種型 (たとえば、pointer_comphttps://stackoverflow.com/a/18940595/981959はSTL の定義によれば透過的ではありませんが、 を定義することでpointer_comp::is_transparent問題の解決に使用できます。またはstd::set<T, C>型のキーを使用して を検索するだけであればT、and型の引数 (どちらの順序でも) でのみ呼び出すことができるため、真に透過的である必要はありません。 この名前を使用したのは、もっと良い名前が思いつかなかったことが一因です (このような関数は静的ポリモーフィズムを使用するため の方が良かったのですが、動的ポリモーフィズムを参照する型特性が既に存在します)。intCTintis_polymorphicstd::is_polymorphic

おすすめ記事