私の「遅延バインディング」を誤解しないでください。実行時の通常の遅延バインディングを意味するのではなく、別のことを意味していて、より適切な言葉を見つけることができません。
これらの値をコンパレーターと比較する必要がContainor
ある値タイプのコンテナー (または同様の) データ構造に取り組んでいるとします。最初のテンプレートは次のようになります。V
template<typename Val, typename Comp = std::less<Val>>
struct Containor{};
現在、私のContainor
構造は別のコンテナを内部的に利用しています。どのコンテナーを使用するかは、テンプレート引数によっても構成可能である必要があります。デフォルトはstd::set
. したがって、次のバージョンの は次のContainor
ようになります。
template<typename Val, typename Comp = std::less<Val>, typename Cont = std::set<Val,Comp>>
struct Containor{};
ここで、コードが私見の匂いを嗅ぎ始めます。ユーザーが内部コンテナーのデフォルトの実装に満足している限り、すべて問題ありません。btree::btree_set
しかし、彼が の代わりに新しい google btree セットの実装を使用したいとしますstd::set
。次に、彼は次のようにテンプレートをインスタンス化する必要があります。
typedef Containor<int,std::less<int>,btree::btree_set<int,std::less<int>> MyContainor;
^^^^^^^^^^^^^^^^^^^
私の問題がある部分に下線を引きました。CLIENT CODE は、適切なパラメーターを使用して btree_set をインスタンス化する必要があります。Containor
クラスは常に、最初の 2 つのテンプレート引数とまったく同じ型とコンパレータのセットを必要とするため、これは正直言って最悪です。クライアントは - 偶然にも - ここに他のタイプを挿入することができます! さらに、クライアントには適切なパラメータを選択するという負担があります。この場合、これは簡単かもしれませんが、たとえば内部コンテナーが値型と他の型のペアのセットでなければならない場合は困難です。その場合、クライアントは内部セットの型パラメーターを正しく取得するのにさらに苦労します。
だから私が望むのは、クライアントコードが生のテンプレートのみを渡し、Containor
内部で正しい引数でそれをインスタンス化する方法です。つまり、次のようなものです。
template<typename Val, typename Comp = std::less<Val>, typename Cont = std::set >
struct Containor{
typedef Cont<Val,Comp> innerSet;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ container instanciates the inner containor
};
typedef Containor<int,std::less<int>,btree::btree_set> MyContainor;
// ^^^^^^^^^^^^^^^^
// client only hands in raw template
もちろん、これは有効な C++ ではありません。
そこで、この問題を解決する方法を考えました。私が考えることができる唯一の解決策は、次のように、使用したいすべてのデータ構造の「バインダー クラス」を記述することでした。
struct btree_set_binder{
template<typename V, typename C = std::less<V>>
struct bind{
typedef btree::btree_set<V,C> type;
}
};
Containor
これで、セットバインダーで自分を定義できます
template<typename Val, typename Comp = std::less<Val>, typename ContBinder = btree_set_binder >
struct Containor{
typedef btree_set_binder::bind<Val,Comp>::type innerSet;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ works like a charm
};
これで、ユーザーは必要なバインダー クラスをContainor
指定するだけで、適切な引数でインスタンス化されます。したがって、これらのバインダー クラスは私にとっては問題ありませんが、すべてのコンテナーに対してバインダー クラスを作成するのは非常に面倒です。したがって、C++ 11でテンプレート引数を「遅く」バインドする、つまり生のテンプレートをパラメーターとして取得する別のテンプレート内にバインドするより良い方法または簡単な方法はありますか。