テンプレートクラスがあります
template<int N>
class xyz{
some code ....
};
クラス内でNを使用しない場合、このクラスのすべてのオブジェクトは、テンプレート値に関係なく互換性があるはずです。しかし、そうではありません。
たとえば、私が言っxyz<20> a
てから、とするとxyz<30> b(a)
、コンパイラはエラーを出します。
なんでそうなの?
テンプレートクラスがあります
template<int N>
class xyz{
some code ....
};
クラス内でNを使用しない場合、このクラスのすべてのオブジェクトは、テンプレート値に関係なく互換性があるはずです。しかし、そうではありません。
たとえば、私が言っxyz<20> a
てから、とするとxyz<30> b(a)
、コンパイラはエラーを出します。
なんでそうなの?
種類が違うからです。この空のクラス テンプレートに対しても
template <int N> struct Foo {};
Foo<1>
とは別のタイプFoo<2>
です。このようなテンプレートがテンプレート パラメーターでインスタンス化されると、テンプレート パラメーターがクラスのコードで使用されているかどうかに関係なく、個別のクラスが作成されます。クラス テンプレートは、いくつかの (テンプレート) パラメータに従ってクラスを構築するためのレシピ (テンプレート) です。
ここで、あるインスタンス化を別のインスタンス化から構築できるようにしたい場合Foo
は、暗黙的な変換コンストラクターを追加できます。
template <int N>
struct Foo
{
template <int M> Foo(const Foo<M>& rhs) {}
};
次に、一方と他方の間で暗黙的に変換できます。
Foo<42> a;
Foo<1> b (a);
Foo<99> c;
c = b;
テンプレート型の等価規則は、スタンダートに明示的に記述されています (パラグラフ 14.4)。ある規則は次のように述べています。
2 つのテンプレート ID が同じクラスまたは関数を参照している場合
- 対応する整数型または列挙型の非型テンプレート引数は、同一の値を持ちます
したがって、数値テンプレート引数が異なれば、実際に使用されるかどうかに関係なく、異なる型が生成されます。後者の場合、テンプレート コピー コンストラクターを使用することができます。
template<int N>
class xyz{
template<int M>
xyz::xyz(const xyz<M>&);
};
の異なる値を使用するたびN
に、コンパイラは新しいクラス定義を作成します。テンプレート値を使用するか、何も変更しません。
関数パラメータについても同じです:
int foo(void) { // foo is of type `int (*)()`
return 1;
}
int bar(int not_used) { // bar is of type `int (*)(int)`
return 1;
}
bar
パラメーターを使用しないでください。ただし、 と同じ署名はありませんfoo
。
foo
またはを同じ変数に割り当てることができないのと同様に(型が異なるため)、とbar
のインスタンスを混在させることはできません。xyz<0>
xyz<1>
これを行いたい場合は、従来の継承の使用を検討する必要があります。
互換性があると言うときは、「コピー構築可能で相互に割り当て可能」という意味だと思います。
int の任意の値でインスタンス化されたクラスを処理するには、コピー コンストラクターと代入演算子を定義する必要があります。
template<int N>
class Foo {
public:
template<int NO>
Foo(const Foo<NO>& other) {
// do stuff
}
template<int NO>
Foo& operator=(const Foo<NO>& other) {
// do stuff
return *this;
}
};
コンパイラにそれをどのように証明してもらいたいですか?
検討:
template<int N>
class xyz{
void foo () {external_function (N);}
};
コンパイラに行って何をするかを確認することをお勧めしexternal_function
ますか?
N が使用されていないという条件でコンパイラに互換性のある型を生成させることに加えて、メンテナンスの悪夢だったでしょう。