引数のないテンプレートコンストラクターを持つ非テンプレートクラスが必要です。
私が理解している限り、それを使用することは不可能です(デフォルトのコンストラクタ-am I right?)、と競合するため、回避策は次のとおりです:
class A{
template <typename U> A(U* dummy) {
// Do something
}
};
たぶん、これに代わるより良い代替手段(またはより良い回避策)がありますか?
コンストラクターテンプレートを呼び出すときに、テンプレート引数を明示的に指定する方法はないため、引数の推論によって推論する必要があります。これはあなたが言うなら:
Foo<int> f = Foo<int>();
<int>
は、そのコンストラクターではなく、Foo
型のテンプレート引数リストです。コンストラクターテンプレートの引数リストはどこにもありません。
回避策を講じても、そのコンストラクターテンプレートを呼び出すには、引数を渡す必要があります。あなたが何を達成しようとしているのか明確ではありません。
テンプレート化されたファクトリー関数を作成できます。
class Foo
{
public:
template <class T> static Foo* create() // could also return by value, or a smart pointer
{
return new Foo(...);
}
...
};
私が理解する限り、それを持つことは不可能です(デフォルトのコンストラクタと競合するためです-私は正しいですか?)
あなたは間違っている。競合することはありません。あなたは今までそれを呼び出すことはできません。
template<class...>struct types{using type=types;};
template<class T>struct tag{using type=T;};
template<class Tag>using type_t=typename Tag::type;
上記のヘルパーを使用すると、値として型を操作できます。
class A {
template<class T>
A( tag<T> );
};
tag<T>
型は、処理する型以外に状態を持たない変数です。これを使用して、純粋な型の値をテンプレート関数に渡し、テンプレート関数によって型を推測できます。
auto a = A(tag<int>{});
複数のタイプを渡すことができます:
class A {
template<class T, class U, class V>
A( types<T,U,V> );
};
auto a = A(types<int,double,std::string>{});
いくつかのポイント:
X
またはX&
またはX const &
を取る)、コンパイラーはデフォルトのコピーコンストラクターを生成します。T const &
またはT
またはT&
をとるクラスXのテンプレートコンストラクターを提供する場合、コンパイラはそれにもかかわらず、デフォルトのテンプレート化されていないコピーコンストラクターを生成します。 T = Xの場合、宣言はコピーコンストラクターの宣言と一致するため、そうすべきではありません。HTH
これを行うことができます:
class C
{
public:
template <typename T> C(T*);
};
template <typename T> T* UseType()
{
static_cast<T*>(nullptr);
}
次に、C
をコンストラクタのテンプレートパラメータとして使用して、タイプint
のオブジェクトを作成します。
C obj(UseType<int>());
テンプレートパラメーターをコンストラクターに渡すことはできないため、このソリューションは基本的にテンプレートパラメーターを通常のパラメーターに変換します。コンストラクターを呼び出すときにUseType<T>()
関数を使用すると、そのパラメーターの目的は、使用する型をコンストラクターに伝えることであることが、コードを見ている人に明らかになります。
これの1つの使用例は、コンストラクターが派生クラスオブジェクトを作成し、それを基本クラスポインターであるメンバー変数に割り当てる場合です。 (コンストラクターは、使用する派生クラスを知る必要がありますが、同じ基本クラスのポインター型が常に使用されるため、クラス自体をテンプレート化する必要はありません。)
のようなことをしてみてください
template<class T, int i> class A{
A(){
A(this)
}
A( A<int, 1>* a){
//do something
}
A( A<float, 1>* a){
//do something
}
.
.
.
};
回避策は次のとおりです。
AのテンプレートサブクラスBを作成します。Aのコンストラクターで、構築のテンプレート引数に依存しない部分を実行します。 Bのコンストラクターでテンプレート引数に依存する部分を実行します。