問題タブ [copy-elision]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
569 参照

c++ - コピー省略の目に見える副作用

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

でコンパイルすると

g++ -std=c++11 -fno-elide-constructors test.cpp

出力は

ctor ctor コピー 0

inは暗黙的に から構築され、Foo b = 10コピーはから構築されるため、これは私が期待するものです。さらに、私のコピー コンストラクターは何もしないので、メンバーは残ります(クラス内で初期化されるため)。10intbFoo_a0

ただし、コピー省略を使用すると

g++ -std=c++11 test.cpp

出力は

ctor ctor 10

控えめに言っても驚くべきことです。ここでコピー コンストラクターが省略されていることは理解していますが、これはコード パスの残りの部分に影響を与えるため、重大な副作用 (メンバーが 0 に初期化され、10 に初期化されるという事実) です。

この動作は正常ですか?

0 投票する
2 に答える
289 参照

c++ - 自動およびコピー省略

auto を使用して特定のタイプにコミットする場合のコピー省略のルールは正確には何ですか? (参照: GotW - ほとんど常に auto )。

私の理解では、move/copy コンストラクターは、一般的には使用されていませんが、アクセス可能である必要があります。しかし、以下の例のunique_ptrfstreamの違いは何ですか? ( noexceptと何か関係がありますか?)

0 投票する
2 に答える
207 参照

c++ - コピーエリシオンの誤解

でコンパイルした後

g++ Copy.cpp -std=c++11 -fno-elide-constructors

出力は次のとおりです。

定義構成

構成をコピー

構成をコピー

そして私の質問は: なぜ 2 Copy Constr なのですか? 必要なコピーは1つだけだと思いました。

func1() が一時オブジェクトをスローし、この一時オブジェクトを別のメモリ領域にコピーする必要があり、その領域から再び func2() パラメータのコピーを作成する必要があると推測するかもしれませんが、私にとってはあいまいです。

詳しく説明していただけますか?

0 投票する
2 に答える
94 参照

c++ - コピー省略が制限されているのはなぜですか?

私が注目しているコピー省略の 2 つの形式は、非常に制限されています。これは、return ステートメント内で、変数を一時変数で初期化する場合にのみ許可されます。したがって、これらにはコピー省略は含まれません。

これの理由は何ですか?それは技術的な制限ですか..それとも..?

0 投票する
2 に答える
247 参照

c++ - テンプレート クラスで呼び出されるデストラクタが多すぎる (N)RVO 最適化

独自のスマート ポインター (C++ 11) とスタックを作成しようとしていますが、次の例で説明できる 1 つの問題があります。

出力:

ご覧のとおり、ここには非常に多くのデストラクタがあります。私の考えでは、copy elision と template-constructor の間の相互作用に何らかの問題がありますが、そのようなバグの理由が何であるかはわかりません。copy-constructorを追加して問題を修正し、explicitコンパイラに template-constructor を強制的に使用させようとしました。

次の出力を得ました:

ここではすべて問題ないように見えますが、クリーンなソリューションには見えません。より良い代替手段はありますか?

0 投票する
4 に答える
1034 参照

c++ - スタック割り当てオブジェクトへのポインタとムーブ構造

注:これは、私がしばらく前に投稿した質問の完全な言い回しです。重複している場合は、もう一方を閉じてください。

私の問題は非常に一般的ですが、具体的な簡単な例に基づいて、より簡単に説明できるようです。オフィスの電力消費量をシミュレートしたいとします。照明と暖房しかないと仮定しましょう。

重要な点は次のとおりです。

1.Timeデータ メンバーに移動できない、LightまたはHeatingその変更がこれらのクラスのいずれにも由来しないため。

2.Timeにパラメーターとして明示的に渡す必要はありませんLight。実際、Lightプログラムのどの部分にも、パラメーターとして提供したくない への参照が存在する可能性がTimeあります。

これで、Simulationコピー/移動が構築されていない限り、完全に見つかります。そうである場合は、コピー/移動も構築され、デフォルトで、Time へのポインターはコピー/移動元の古いインスタンスをLight指しているからです。ただし、実際に、return ステートメントとオブジェクト作成の間で copy/move が構築されます。TimeSimulationSimulationSimulationBuilder::build()main()

現在、問題を解決する方法はいくつかあります。

1: コピー省略に依存します。この場合(そして私の実際のコードでは)、コピーの省略は標準で許可されているようです。しかし必須ではなく、実際のところ、clang -O3 によって省略されることはありません。より正確に言うと、clang はSimulationコピーを省略しますが、move ctor for を呼び出しますLight。また、実装依存の時間に依存することは堅牢ではないことに注意してください。

2: で move-ctor を定義しSimulationます。

これは機能しますが、ここでの大きな問題はカプセル化を弱めることです:移動中により多くの情報が必要でSimulationあることを知る必要があります。Lightこの単純化された例では、これはそれほど悪くはありませんが、timePtr直接ではなくLight、そのサブサブサブメンバーの 1 つにあると想像してください。それから私は書かなければならないでしょう

これは、カプセル化とデメテルの法則を完全に破ります。関数を委任するときでさえ、私はそれが恐ろしいと思います。

Time3: によって監視されているある種のオブザーバー パターンを使用し、メッセージを受信するときにポインターを変更するLightように、コピー/移動が構築されているときにメッセージを送信します。Light私はそれの完全な例を書くのが面倒だと告白しなければなりません。

4: で所有ポインタを使用しますSimulation

が移動Simulationすると、Timeメモリは ではないため、 のポインタLightは無効になりません。実際、これは他のほとんどすべてのオブジェクト指向言語が行うことです。すべてのオブジェクトはヒープ上に作成されるからです。今のところ、私はこの解決策を支持していますが、まだ完全ではないと考えています。B. Stroustrup が、必要のないときはポインタを使用すべきではなく、必要な場合は多かれ少なかれポリモーフィックであることを意味すると言っているのを聞いたことがあります。

5:Simulation返されることなく、その場で構築しSimulationBuilderます (その後、コピー/移動 ctor/代入をSimulationすべて削除できます)。例えば

今、私の質問は次のとおりです。

1: どのようなソリューションを使用しますか? もう一つ考えてみませんか?

2: 元のデザインに何か問題があると思いますか? それを修正するためにあなたは何をしますか?

3: このようなパターンに遭遇したことがありますか? 私のコード全体でかなり一般的です。Timeただし、実際にはポリモーフィックであり、ヒープが割り当てられているため、一般的にはこれは問題ではありません。

4: 問題の根本に戻ると、「移動する必要はありません。移動できないオブジェクトをその場で作成したいだけですが、コンパイラはそうすることができません」なぜないのですか? C ++での簡単な解決策と、別の言語での解決策はありますか?

0 投票する
2 に答える
444 参照

c++ - 値で一時的に渡すときに移動の省略を回避するにはどうすればよいですか?

次のコードでは:

Widget オブジェクトは常にインプレース (foo 関数内) で構築されるため、move 構築は行われません (少なくとも私が試したすべてのコンパイラで)。move の構築が実際に行われる方法で一時的な値を関数に渡す簡単な例は何ですか?