ユーザーは、必要なオプションを指定するクラスを定義することにより、ライブラリテンプレートクラスをカスタマイズします。それをマニフェストと呼びます。マニフェストにオプションのtypedefを含めるという考え方です。たとえば、ユーザーのマニフェストにHのtypedefが含まれている場合、ライブラリコードで指定されたタイプを「H」として使用する必要があります。ユーザーのマニフェストにtypedefがない場合、ライブラリはデフォルトを使用します。
新しいC++11機能を利用してこれを行うためのエレガントな方法があると思いますが、私は空っぽになっています。SFINAEのウィキペディアエントリに基づいた解決策があります。醜いです。新しいHごとに新しいテンプレート関数has_typedef_Hが必要です。0が整数またはnullポインターのいずれかを意味するというプロパティを悪用するのは、漠然と不安です。あまりにもクルージーのようです。
もっと良い方法はありますか?できればVC++2010で動作するものですか?
おもちゃの例では、H1、H2、U0、U1、U2の5つのクラスがあります。H1とH2は、ライブラリクラスLの「ヘルパー」の例です。H1がデフォルトです。Uは、ユーザー定義クラスの例です。この例では、ライブラリクラスLの定義を省略し、main()の本体を使用して、Uのtypedef(またはその欠如)に基づいてHを選択しました。タイプH2の主題。
struct H1{
void operator() (){ std::cout << "H1" << std::endl;}
};
struct H2{
void operator() (){ std::cout << "H2" << std::endl;}
};
struct default_H: public H1 {};
struct U2 {
typedef H2 H;
};
struct U1 {
typedef H1 H;
};
struct U0 {
};
template <typename T>
class has_typedef_H {
typedef char no[false+1];
typedef char yes[true+1];
template
static yes& test(typename C::H*);
template
static no& test(...);
public:
static const bool value = sizeof(test(0))-1;
};
template<typename U, bool >
struct type_H_B: public default_H{};
template<typename U>
struct type_H_B<U, true>: public U::H {};
template<typename U>
struct H_type: public type_H_B<U, has_typedef_H<U>::value> {};
int main() {
H_type<U0> h0;
H_type<U1> h1;
H_type<U2> h2;
// Prints H1 H1 H2
h0();
h1();
h2();
return 0;
}