6

コピーコンストラクターと代入演算子をテンプレートバージョンでオーバーロードすることについてこの質問をし、質問に関連する混乱を考慮して(コンパイラのバグのように見えるため)、テンプレートコピーコンストラクターとテンプレート代入演算子のみを使用して試してみようと思いました何が起こるか見てください。しかし、それらはコンパイラによって完全に無視されます。

struct BaseClass
{
public:
  BaseClass() {}

  template<typename T>
  BaseClass(const T& a_other)
  {
    int i = 0; // for break point which is not hit
  }

  template<typename T>
  BaseClass& operator= (const T& a_other)
  {
    int i = 0; // for break point which is not hit
    return *this;
  }

};

struct MyClass : public BaseClass
{
};

int main()
{
  MyClass i, j;
  i = j;

  return 0;
}

テンプレート バージョンでデフォルトをオーバーライドできないのはなぜですか (答えは、デフォルトの方が適切であると思われますが、テンプレート バージョンもデフォルトとして機能するようにしたいと考えています)。そして、デフォルトの代わりにテンプレートのバージョンが呼び出されるようにするためにできることはありますか?

4

2 に答える 2

8
template<typename T>
BaseClass(const T& a_other) 

まず、これはコピー コンストラクターではありません。むしろテンプレート化されたコンストラクターです。

コピー コンストラクターは次のようにする必要があります。

BaseClass(const BaseClass & a_other)

違いに気づきましたか?

テンプレート化されたコンストラクターはcopy-constructorを定義しないことに注意してください。コンパイラは、テンプレート化されたコンストラクターをインスタンス化する代わりに、デフォルトのコピー コンストラクターを生成します

copy-assignment と同じ引数。

于 2012-02-28T18:49:50.883 に答える
5

他の質問への回答で述べたように、標準では明確に禁止されています。

これらのコンストラクターのデフォルト以外が必要な場合、問題のクラスの詳細に対処する必要があるため、その論理的根拠があると思います。「一般的な」ソリューションは意味がなく、潜在的な問題を静かに隠す可能性があります。

一部の人々は、これらの関数の「一般的な」暗黙的なバージョンが既に存在することは十分に悪いと考えるかもしれません。これは、多くのクラスに対して暗黙のうちに間違ったことを行います。

これらの標準的な禁止テンプレートのバージョンは次のとおりです。

C++03 12.8 から「クラス オブジェクトのコピー」

  • (Para 1): クラス X の非テンプレートコンストラクターは、最初のパラメーターが X&、const X&、volatile X&、または const volatile X& 型であり、他のパラメーターがないか、他のすべてのパラメーターに既定値がある場合、コピー コンストラクターです。引数 (8.3.6)
  • (Para 9): ユーザー宣言のコピー代入演算子 X::operator= は、型 X、X&、const X&、volatile X&、または const volatile X& のパラメーターを 1 つだけ持つ、クラス X の非静的非テンプレートメンバー関数です。
于 2012-02-28T18:50:28.340 に答える