[解決済み] トランスペアレントコンパレータとは?
質問
C++14では、連想コンテナはC++11から変更されたようです - [associative.reqmts]/13に書かれています。
メンバー関数のテンプレートである
find
,count
,lower_bound
,upper_bound
そしてequal_range
という型がない限り、オーバーロードの解決に参加しないものとします。Compare::is_transparent
が存在しない限り、オーバーロードの解決に参加しない。
コンパレータを "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>, ...
であるため、デフォルトのセットでは
find
,
count
などのメンバーですか?
どのように解決するのですか?
<ブロッククオートどのような問題を解決するのですか。
参照 ディートマールの回答 および リミーベルの回答 .
で、これによって標準的なコンテナの動作が変わるのでしょうか?
いいえ、デフォルトではありません。
新しいメンバー関数テンプレートのオーバーロードは
find
などでは、キーの型そのものを使うのではなく、コンテナのキーと比較可能な型を使うことができます。 以下を参照してください。
N3465
Joaquín Mª López Muñoz による、この機能を追加するための根拠と詳細かつ慎重に書かれた提案を参照してください。
ブリストルでの会議で、LWG は heteregeneous lookup 機能が有用で望ましいということに合意しましたが、Joaquín の提案がすべてのケースで安全であるとは断言できませんでした。N3465 の提案は、いくつかのプログラムにとって深刻な問題を引き起こしたことでしょう ( 既存のコードへの影響 の項を参照)。Joaquín は、異なるトレードオフを持ついくつかの代替実装を含む最新のドラフト提案を準備し、LWG が長所と短所を理解するのに非常に役に立ちましたが、それらはすべて何らかの形でいくつかのプログラムを破壊するリスクがあったため、その機能を追加することに同意することはできませんでした。 私たちは、無条件に機能を追加するのは安全ではないが、デフォルトで無効にして、" opt in" だけであれば安全であろうと判断しました。
の重要な違いは
N3657
提案 (これは、私と STL が
N3465
と Joaquín による後の未発表の草稿に基づく) の提案では、この草稿に
is_transparent
型を追加することでした。
もしあなたが "透明なファンクタ" (つまり
is_transparent
型を定義するもの) を使用しない場合、コンテナはこれまでと同じように動作し、それはまだデフォルトのままです。
もし、あなたが
std::less<>
(C++14 の新機能) または別の透過型ファンクタ "transparent functor" 型を使用する場合は、新しい機能を使用できます。
使用方法
std::less<>
を使うのは、エイリアス テンプレートを使えば簡単です。
template<typename T, typename Cmp = std::less<>, typename Alloc = std::allocator<T>>
using set = std::set<T, Cmp, Alloc>;
名前
is_transparent
はSTLの
N3421
から来ており、C++14 に "ダイヤモンド演算子" が追加されました。透明なファンクタとは、任意の引数型(同じである必要はありません)を受け入れ、それらの引数を単に別の演算子に転送するものです。 このようなファンクタは,まさに連想コンテナの異種間ルックアップに必要なもので,そのため,型
is_transparent
という型がすべてのダイアモンド演算子に追加され、新しい機能が連想コンテナで有効であることを示すタグ型として使用されました。技術的には、コンテナには "透明なファンクタ" は必要なく、異種型での呼び出しをサポートするものだけです(たとえば
pointer_comp
の型
https://stackoverflow.com/a/18940595/981959
は、STLの定義によれば透過的ではありません。
pointer_comp::is_transparent
を定義することで、問題を解決するために使用することができます)。もし、あなたが一度だけ、あなたの
std::set<T, C>
のキーで
T
または
int
では
C
という型の引数で呼び出せるだけである。
T
そして
int
(のどちらかであれば)、本当に透明である必要はありません。 私たちがこの名前を使ったのは、より良い名前を思いつかなかったからでもあります(私は、より良い
is_polymorphic
というのは、このようなファンクタは静的ポリモーフィズムを使うからですが、すでに
std::is_polymorphic
の型特性は動的ポリモーフィズムを参照しているからです)。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない
-
[解決済み] カスタムstd::setコンパレータを使用する
-
[解決済み】古典的なソートアルゴリズムを最新のC++で実装する方法とは?