2

特定のクラスAがパブリック コピー コンストラクターとプライベート ムーブ コンストラクターで定義されているとします。関数が typeのfオブジェクトを返し、 typeの変数のローカル インスタンスを初期化するために使用される場合、既定では (返される値が a であるため)、コンパイラは move コンストラクターを使用しようとします。移動コンストラクターがプライベートであることを検出したら、コンパイラーがコピー コンストラクターを使用することを期待するのが賢明だと思いましたが、驚いたことに、移動コンストラクターがプライベートであることを示すコンパイラ エラーを受け取りました。次のコードを考えると、私の質問は次のとおりです。AfArvalue

 #include<iostream>

 using namespace std;

 class A
 {

    friend A f();

 public:
    A(const A&) { cout << "copy\n"; }


 private:
    A() {}
    A(A&&) { cout << "move\n"; }
 };

 A f()
 {
    A a;
    return a;
 }

 int main()
 {
    A a = f();
 }

コピー コンストラクターを使用して main の変数を初期化できるように (A または f を変更せずに) コードを変更するにはどうすればよいですか?

4

2 に答える 2

1

呼び出す関数を選択するために、最初に過負荷解決が実行されます。

アクセスチェックは後のステップとして実行され、選択した関数/コンストラクターを呼び出すことができるかどうかをチェックします。

これは意図的に行われるため、プライベート関数は呼び出されません(プライベートであるため。その場合、コンパイラに呼び出す別の関数を選択させることは生産的ではありません。

于 2012-10-19T19:27:57.190 に答える
1

意味がないのでクラスを変更します。

または、クラスから派生するか、ラップします。

簡単なハックが必要な場合は、次のことができます

template< class Type >
Type& tempref( Type&& t ) { return t; }

それからする

A a = tempref( f() )

免責事項: コンパイラの手によって触れられていないコード。

于 2012-10-19T19:30:25.677 に答える