7

次のコードを検討してください。

class A {
  A(const A&);
 public:
  A() {}
};

int main() {
  const A &a = A();
}

このコードはGCC4.7.2で正常にコンパイルされますが、Visual C ++ 2010でコンパイルできず、次のエラーが発生します。

test.cc(8) : error C2248: 'A::A' : cannot access private member declared in class 'A'
        test.cc(2) : see declaration of 'A::A'
        test.cc(1) : see declaration of 'A'

では、一時を参照にバインドするときに、コピーコンストラクターにアクセスできるようにする必要がありますか?

これは私の前の質問にいくらか関連しています:

const参照への一時的なバインドを無効にする方法はありますか?

4

3 に答える 3

4

では、一時を参照にバインドするときに、コピーコンストラクターにアクセスできるようにする必要がありますか?

ポストC++11-いいえ
プレC++11-はい。


このコードは、C ++ 11標準に準拠しているため、GCC4.7.2で正常にコンパイルされます。

C ++ 11標準では、const参照をから初期化する場合prvalue、参照オブジェクトに直接バインドする必要があり、一時的なものを作成することはできません。また、コピーコンストラクタは使用または必須ではありません。

C ++ 11より前は、ルールは異なっていました。そして、この動作(コピーコンストラクターが呼び出されるかどうか)は実装によって定義されます。C ++ 03では、const参照を一時参照にバインドしているときにコピーコンストラクターを呼び出すことができたため、C ++ 11以降では、コピーコンストラクターにアクセスできる必要があります。Visual C ++ 2010は、C++03標準に準拠しています。

于 2012-12-16T05:23:40.527 に答える
2

C ++ 03標準のセクション8.5.3.5には、これは実装定義であると記載されています。

初期化式が右辺値であり、T2がクラス型であり、「cv1T1」が「cv2T2」と参照互換である場合、参照は次のいずれかの方法でバインドされます(選択は実装定義です)。

-参照は、右辺値(3.10を参照)で表されるオブジェクト、またはそのオブジェクト内のサブオブジェクトにバインドされます。

--タイプ"cv1T2" [sic]の一時オブジェクトが作成され、コンストラクターが呼び出されて、右辺値オブジェクト全体が一時オブジェクトにコピーされます。参照は、一時または一時内のサブオブジェクトにバインドされます。

コピーを作成するために使用されるコンストラクターは、コピーが実際に実行されるかどうかに関係なく呼び出し可能でなければなりません。

したがって、両方の実装がC++03標準と一致しているように見えます。

最後の文は少し紛らわしいですが、私がそれを読む方法は、実装が2番目の方法を選択する可能性があることを意味しますが、それでもコピーを最適化します。その場合、戻り値の最適化と同様に、コピーが実際に行われていなくても、コピーコンストラクターにアクセスできる必要があります。

C ++ 11標準では、2番目の方法はオプションではなくなりました。

于 2012-12-16T05:11:52.980 に答える
0

VisualC++は正しくありません。const標準では、参照を一時的なものにバインドするためにコピーコンストラクターにアクセスできる必要があることは示されていません。

于 2012-12-16T05:06:39.627 に答える