1

コード

class ElisionTest
{
public:
    int n;
    // ElisionTest(ElisionTest& other): n(other.n) {cout<<"copy constructor"<<endl;}
    ElisionTest(int n): n(n) {cout<<"constructor"<<endl;}
};

int main(int argc, char const *argv[])
{
    ElisionTest et = 10;

}

印刷"constructor"され、それで問題ありません。ここで、コピー コンストラクターのコメントを外すと、コンパイル時エラーが発生します。

cpp_test.cpp: In function 'int main(int, const char**)':
cpp_test.cpp:140:19: error: no matching function for call to 'ElisionTest::ElisionTest(ElisionTest)'
cpp_test.cpp:140:19: note: candidates are:
cpp_test.cpp:135:2: note: ElisionTest::ElisionTest(int)
cpp_test.cpp:135:2: note:   no known conversion for argument 1 from 'ElisionTest' to 'int'
cpp_test.cpp:134:2: note: ElisionTest::ElisionTest(ElisionTest&)
cpp_test.cpp:134:2: note:   no known conversion for argument 1 from 'ElisionTest' to 'ElisionTest& {aka ElisionTest&}'

これはおそらく、コピー コンストラクターが一時的に呼び出されることを示していますElisionTest(10)。また、一時的なものへの非 const 参照を持つことはできないため、コピー コンストラクターの引数を a にconst&することでエラーが解決されるはずです。

しかし、コピー コンストラクターをのconst ElisionTest&代わりに取得するように変更するElisionTest&と、エラーは発生せず、出力は"constructor"再び表示されます。なぜ印刷されなかったの"copy constructor"ですか?

4

2 に答える 2

2
ElisionTest(ElisionTest& other);

その署名を持つコンストラクターはElisionTest、左辺値を介してインスタンスの初期化を許可します。これを行う場合:

ElisionTest et = 10;

ElisionTestこれにより、一時的なものからのインスタンスが構築されます。あなたのコードは以下と同等です:

ElisionTest et = ElisionTest(10);

これにより、const 以外の参照を受け取るコンストラクターが呼び出され、それで初期化etされます。ただし、const 以外の参照をテンポラリにバインドすることはできません。constそのため、左辺値と右辺値の両方をサポートできるように、コピー コンストラクターに追加する必要があります。

ElisionTest(ElisionTest const& other);
//                      ^^^^^

出力が表示されない理由は、copy-elisionと呼ばれるものが原因です。コンパイラは、コピー/移動コンストラクターへの呼び出しを省略できます。-fno-elide-constructorsGCC では、 copy-elision をオフにするために使用できます。

于 2013-06-16T19:00:42.357 に答える
1

からに"constructor"変換する必要があるため、出力します。10ElisionTest

"copy constructor"最適化されていないため(コピー省略)、印刷もされませんでした。これは、プログラムの観察可能な動作を変更できる唯一の最適化です。

于 2013-06-16T19:02:37.907 に答える