コンパイラの作成者から集めたものに基づいて、効率の点で値型は参照/ポインターよりもはるかに好まれます。
これは、エイリアシング、外部で変更されたメモリ (ポインターが参照する)、ポインター逆参照のコストなどを気にする必要がない場合、値型の方が簡単に推論できるという事実に由来します。そのような懸念は理解していますが、特定のケースに関してまだいくつか質問があると言わざるを得ません。
ケース #0
void foo(const float& f)
さて、ここに参照がありますが、それは一定です! 確かに、私たちはそれの一定のビュー (参照) を持っているので、外部的には変更される可能性がありますが、それはマルチスレッドの世界でのみ発生する可能性があり、同期プリミティブが使用されていない場合、コンパイラがそれをまったく考慮する必要があるかどうかはわかりません. 明らかに、float 変数への別のポインター/参照を内部的に使用した場合、f
パラメーターを変更するリスクがある可能性があります。コンパイラはこのパラメーターを安全なものとして扱うことができますか (ref/ptr を使用して内部的に浮動させることはないと仮定します)?
ケース #1
void foo(vector<int> f)
C++11/14 プログラマーの観点から言えば、vector
を安全に関数に移動できることはわかっています。ご存知のように、コンテナは内部的に配列へのポインタを保持しています。vectorのコピーを取得したばかりなので、コンパイラはポインターを安全 (外部からの変更なし) として扱うので、その所有者は私たちだけでしょうか?
言い換えれば、コピーされたオブジェクトが安全なものとして扱われる (論理的にはオブジェクトのクローンを作成するため)、またはコンパイラがそのような仮定を行うことを許可されておらず、 ptr/ref メンバーを潜在的に危険なものとして扱わなければならないcopy ctor/op が適切なコピーを作成していない可能性があります。プログラマーは、共有リソースをコピーするときにそれらを処理する責任を負うべきではありませんか?
要点:
定数ポインター/参照およびコピーされた複雑なオブジェクトは、一般にプリミティブのコピーよりも低速であるため、パフォーマンスが重要なコードではできる限り回避する必要があります。それとも、わずかに効率が悪いだけで、心配する必要はありませんか?