3

この投稿に関連して、この動作について説明してください。

#include <stdio.h>

struct B { B(B&) { } B() { } };
struct A {
  template<typename T>
  A(T&){ printf("A(T&)\n"); }
  A() { }
//  B b; // when this is uncommented, output changes 
  int i;
};

int main() {
  A a;
  A b(a);

// B b; commented:
// template wins:
//   A<A>(A&)  -- specialization
//   A(A const&); -- implicit copy constructor
// (prefer less qualification)

// B b; uncommented:
// implicit copy constructor wins:
//   A<A>(A&)  -- specialization
//   A(A&); -- implicit copy constructor
// (prefer non-template)

  printf("\nA\n");
  A const a1;
  A b1(a1);

// B b; commented:
// implicit copy constructor wins: 
//   A(A const&) -- specialization
//   A(A const&) -- implicit copy constructor
// (prefer non-template)

// B b; uncommented:
// template wins:
//   A(A const&) -- specialization
// (implicit copy constructor not viable)
}

B b の場合、出力が変化します。はコメント解除されています。

どうやら、暗黙のコピーコンストラクターは、コメントが解除されたときにからA(A const&)に変更されます。なんで?コピー コンストラクタに変更すると、 に戻ります。これで、コンパイラは、の仮パラメータが?になることに満足しています。これは規格と関係がありますか?(gcc 4.2.4 を使用しています。)A(A &)B b;B(B&){}B(const B&){}A(A const&)A()const

4

2 に答える 2

4

class の暗黙的なコピー コンストラクターのシグネチャは、Afeasibleの場合A(const A&)のみです。行のコメントを外すと、このコピー コンストラクターは実行できません。これは、コピー コンストラクターが非 const 入力パラメーターを必要とするためです。B b;B

// Illegal implicit copy constructor
A::A(const A& a) :
b(a.b),  // This line would be illegal because a.b is const
i(a.i)
{
}

この場合、暗黙のコピー コンストラクターも非 const バージョンですA(A&);

// Legal implicit copy constructor
A::A(A& a) :
b(a.b),  // Fine: a.b is now non-const
i(a.i)
{
}

B b;これが、クラス定義でコメントを解除すると、暗黙のコピー コンストラクターが変更され、その結果、プログラムの動作が変更される理由です。

編集:直接関係はありませんが、完全を期すために:Bアクセス可能なコピーコンストラクターがない場合(宣言privateまたは削除されているため)、A暗黙のコピーコンストラクターはありません。

于 2012-12-17T12:12:27.003 に答える
3

はい、この動作は 12.8/8 の標準で明確に定義されています。

クラスの暗黙的に宣言されたコピー コンストラクターは、Xif X::X(const X &)[... これが意味をなす条件 ...] の形式を持ち、それ以外の場合は [it] の形式を持ちますX::X(X &)

実際、クラスAに member がある場合B、const 形式は使用できないため、暗黙的に宣言されたコピー コンストラクターは非 const 形式を取ります。

テンプレート化されたコンストラクターは決してコピーコンストラクターではないことに注意してください。

于 2012-12-17T12:13:35.573 に答える