2017-05-29 25 views
3

私が正しく理解している場合、C++ 17から始まる、このコードは、今はコピーが行われないことを必要とします:ファンクションパラメータによるコピーエリジョンの動作は保証されていますか?

Foo myfunc(void) { 
    return Foo(); 
} 

auto foo = myfunc(); // no copy 

それは、関数の引数のためにも、本当ですか?コピーは次のコードで最適化されますか?

Foo myfunc(Foo foo) { 
    return foo; 
} 

auto foo = myfunc(Foo()); // will there be copies? 
+7

注:C++ 17を使用しているので、関数がパラメータを取らない場合はなぜまだ 'void'を置いていますか? – Rakete1111

+1

@ Rakete1111には、その 'void'を置くために必要な標準がありましたか?私の時間がずっとずっと前にC++であったに違いない。 – user463035818

+0

@ tobi303わからない。たぶんC++が標準化されていたのかもしれませんが、それはまだCに基づいていました。でも、わかりません。 – Rakete1111

答えて

2

C++ 17では、prvalues( "anonymous temporaries")はもはやオブジェクトではありません。代わりに、オブジェクトの作成方法に関する指示です。

建設指示から一時的にインスタンス化することができますが、オブジェクトが存在しないため、が存在しません。コピー/移動の構成はありません。だからここ

Foo myfunc(Foo foo) { 
    return foo; 
} 

、関数の引数foomyfuncのprvalue戻り値に移動されます。これは概念的には「myfuncFooの作り方に関する説明を返します」と考えることができます。これらの命令がプログラムで使用されていない場合は、一時的に自動的にインスタンス化され、それらの命令が使用されます。

auto foo = myfunc(Foo()); 

ここで、Foo()は値です。それは "()コンストラクタを使用してFooを構築する"と言います。それは次にmyfuncの引数を構築するために使用されます。エリシジョンは発生せず、コピーコンストラクタまたはムーブコンストラクタは呼び出されず、ただ()となります。

これはmyfuncの中で起こります。

myfuncは、Fooの正価を返します。このprvalue(別名構築命令)は、ローカル変数auto fooを構築するために使用されます。

だから、は()で構築され、次にauto fooに移動されます。

戻り値への関数の引数の削除は、私が知っている限り、C++ 14やC++ 17ではサポートされていません(私は間違っている可能性があります、ここでは標準と章はありません)。しかし、return func_arg;コンテキストで使用されると暗黙的に移動されます。

1

はい、いいえ。 [...]以下の状況で

、コンパイラは、著作およびクラスオブジェクトのmove-構成を省略するために必要とされる:cppreferenceを引用初期において

  • 、初期発現場合ソース値型のCV非適合バージョンが宛先のクラスと同じクラスであり、イニシャライザ式が宛先オブジェクトを初期化するために使用される

  • 戻り値のオペランドステートメントはprvです関数の戻り値の型は、そのprvalueの型と同じです。

だから、あなたの第二のスニペットで唯一のデフォルトコンストラクタが呼び出されます。最初に、foomyFuncは、Foo()(1つのデフォルト構成)から初期値に設定されます。これは、それが省略されることを意味します(ポイント1を参照)。

次に、はfooが省略されているため、省略することはできません(ポイント2)。fooのコピーを返します。したがって、1つの移動が行われます。fooはxvalueです。しかし、実際の戻り値は、foomyFunc)の新しいインスタンスであり、ポイント1のために省略されています。

結論として、1つのデフォルト構成と1つの移動が標準によって保証されています。それ以上はありえません。しかし、コンパイラは実際には唯一の動きを完全になくすかもしれません。

+2

コピー?私はあなたが移動を意味すると思います。 C++標準での構造を取り除くことは、if-ifルールとは異なるものを指します。あなたはエリーディングを使うことを意味しましたか? – Yakk

+0

そしてC++ 17では、ある種のものをオブジェクトにしません。省略された移動/コピーは発生しません。 – Yakk

+0

@Yakkはい、そうですよ! :)しかし、私はnot-objectsについてのあなたの点を理解していません。あなたは詳細を教えていただけますか? – Rakete1111

関連する問題