[解決済み】C++では値で渡すのと定数参照で渡すのはどちらが良いのでしょうか?
質問
C++では、値で渡すのと定数参照で渡すのとどちらが良いのでしょうか?
どっちがいいんだろう? 定数参照で渡すと、変数のコピーを作成しないので、プログラムのパフォーマンスが向上するはずだと理解しています。
どのように解決するのですか?
以前は、一般的に推奨されるベストプラクティスでした
1
に対して
には const ref によるパスを使用します。
すべてのタイプ
ただし、組み込み型 (
char
,
int
,
double
など)、イテレータと関数オブジェクトの場合
(から派生したクラス)。
std::*_function
).
が存在する以前は特にそうでした。 移動セマンティクス . 理由は簡単で、値で渡すとオブジェクトのコピーを作らなければならず、非常に小さなオブジェクトを除いて、これは参照を渡すよりも常に高くつくからです。
C++11で、私たちは 移動セマンティクス . 簡単に言うと、移動セマンティクスは、場合によっては、オブジェクトをコピーせずに「値で」渡すことを許可しています。特に、渡すオブジェクトが 値 .
それ自体、オブジェクトの移動は、少なくとも参照渡しと同じくらいコストがかかります。しかし、多くの場合、関数は内部的にオブジェクトをコピーすることになります。 所有権 引数の 2
このような状況では、次のような(単純化した)トレードオフが成立します。
- オブジェクトを参照渡しして、内部でコピーすればよい。
- オブジェクトを値で渡すことができる。
"値で渡す "場合でも、オブジェクトがrvalueでない限り、オブジェクトはコピーされます。rvalueの場合、代わりにオブジェクトを移動させることができます。そのため、2番目のケースは突然「コピーしてから移動」ではなく、「移動してから(潜在的に)もう一度移動」になっています。
適切な移動コンストラクタを実装しているラージオブジェクト(ベクトル、文字列など)の場合、2番目のケースは次のようになります。 大いに よりも効率的です。したがって、次のようにすることが推奨されます。 関数が引数の所有権を持ち、オブジェクトの型が効率的な移動をサポートしている場合は、値渡しを使用します。 .
歴史的なメモです。
実際、現代のコンパイラは、値による受け渡しが高価であることを把握し、可能であれば const ref を使用するように呼び出しを暗黙的に変換することができるはずです。
理論的には。 実際には、コンパイラは関数のバイナリインタフェースを壊さずにこれを変更できるとは限りません。いくつかの特殊なケース(関数がインライン化されている場合)では、コンパイラが関数内のアクションによってオリジナルのオブジェクトが変更されないことを理解できれば、コピーは実際にエライドされます。
しかし、一般的にはコンパイラはこれを判断できず、C++の移動セマンティックスの出現により、この最適化はあまり意味をなさなくなりました。
1 例:スコット・マイヤーズで。 エフェクティブ C++ .
2 これは特にオブジェクトのコンストラクタによく当てはまります。コンストラクタは引数を受け取り、それを内部に保存して構築されたオブジェクトの状態の一部とすることができます。
関連
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み】Enterキーを押して続行する
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む
-
[解決済み] 変数を参照渡しする方法を教えてください。
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] Static readonly」対「const」。
-
[解決済み] JavaScriptに定数はありますか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】fpermissiveフラグは何をするのですか?
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件
-
[解決済み】'std::cout'への未定義の参照