コピーコンストラクターの定義 [[class.copy.ctor/1] :
クラスXの非テンプレートコンストラクターは、最初のパラメーターの型がX&、const X&、volatile X&またはconst volatile X&であり、他のパラメーターがないか、他のすべてのパラメーターにデフォルトの引数がある場合([dcl。 fct.default])。
標準がテンプレートをコピーコンストラクタとして除外するのはなぜですか?
この単純な例では、両方のコンストラクターがコピーコンストラクターです。
struct Foo {
Foo(const Foo &); // copy constructor
Foo(Foo &); // copy constructor
};
次の同様の例を参照してください。
struct Foo {
Foo() = default;
template <typename T>
Foo(T &) {
printf("here\n");
}
};
int main() {
Foo a;
Foo b = a;
}
この例では、here
が出力されます。したがって、私のテンプレートコンストラクターはコピーコンストラクターのようですが、少なくとも1つと同じように動作します(コピーコンストラクターが通常呼び出されるコンテキストで呼び出されます)。
テキストに「テンプレートではない」要件があるのはなぜですか?
コピーコンストラクターの形式はX(X&)または(X const&)であり、自分で宣言しなかった場合はコンパイラーによって提供されます。非テンプレートがここに来るのは、おそらくテンプレートクラスを使用する場合の問題が原因です。
テンプレートコピーコンストラクターを持つテンプレートクラスがあるとします。問題は、同じテンプレートタイプでこのクラスの別のインスタンスを使用してそのクラスをインスタンス化すると、テンプレートコピーコンストラクターが呼び出されないことです。
問題は、コピーコンストラクターテンプレートが一致しないことではありません。問題は、暗黙的なコピーコンストラクターが関数テンプレートではないことであり、オーバーロードの解決に関しては、テンプレートの特殊化よりも非テンプレートが推奨されます。