2

C++11

move コンストラクターの使用に問題があります。という単純なコンテナ クラスがありNumber、その唯一のデータ メンバは整数です。次のコードがあります。

//Number.h
#ifndef NUMBER_H
#define NUMBER_H
#include <iostream>

class Number
{
public:
    Number();
    Number(int ipar);
    Number(const Number& src);
    Number(Number&& src);
private:
    int num;
};

#endif

//Number.cpp
#include "Number.h"

Number::Number()
{
    std::cout << "default ctor" << std::endl;
}

Number::Number(int ipar) : num(ipar)
{
    std::cout << "integer argument ctor" << std::endl;
}

Number::Number(const Number& src) : num(src.num)
{
    std::cout << "copy ctor" << std::endl;
}

Number::Number(Number&& src) : num(src.num)
{
    std::cout << "move ctor" << std::endl;
}

//main.cpp
#include "Number.h"
using namespace std;

int main()
{
    cout << "Part A:" << endl;
    Number n1(1);
    cout << "Part B:" << endl;
    Number n2(n1);
    cout << "Part C:" << endl;
    Number n3{Number{n1}};
    cout << "Part D:" << endl;
    Number n4(Number(n1));
    return 0;
}

これは以下を出力します:

Part A:
integer argument ctor
Part B:
copy ctor
Part C:
copy ctor
Part D:

パート D の出力がないことに注意してください。パート A と B の出力は期待どおりですが、その他の出力はそうではありません。

パート C と D でこれを期待していました。

Part C:
copy ctor
move ctor
Part D:
copy ctor
move ctor

パート C の期待:

Number{n1}の部分はNumber n3{Number{n1}}一時的な名前のないNumberオブジェクトを作成することを期待していNumberましたn1Number n3次に、一時オブジェクトを使用して移動コンストラクターを呼び出すことで構築されることを期待していました。

パートDへの期待:

これはパート C に似ていますが、中括弧の代わりに括弧が使用されている点を除けば、このパートがパート C と同じように動作し、出力されることを期待していました。

質問:

実際の出力が期待と異なるのはなぜですか? また、目的の出力を得る正しい方法は何ですか?

注:これを Visual Studio でコンパイルする場合は、統一された初期化構文をサポートするために、Visual Studio 2012 用のVisual C++ コンパイラ 2012 年 11 月 CTP以降が必要です。

4

1 に答える 1

3

n4 は関数宣言です。コピー省略n3が原因です。

ここで、コピーの省略を回避するために有効にしたことを確認してください次に、一連のコピー コンストラクターとムーブ コンストラクターを示します。-fno-elide-constructorsn3

n4オブジェクトとして使用しようとするコメントアウトされた行があります。コメントを外すと、代わりに関数であることを示すコンパイラ エラーが表示されます。

n4関数宣言として解釈されないため、関数パラメーターとして表示されないように、一時変数の周りに追加の括弧を配置できますNumber n4((Number(n1)))。これで-fno-elide-constructors、あなたが期待したすべてが起こります。

-fno-elide-constructorsMSVC のオプションとして存在しないことに注意してください。

于 2013-03-01T07:03:07.477 に答える