参照の使い方

Herb Sutter によるブログ投稿に続いて、参照をいつ、どのように使用するかを説明します。

  • 入力パラメーターを変更する必要がない場合は、コピーした方が安価であることがわかっていない限り、const 参照を使用します (疑わしい場合は参照を使用します)。
  • パラメータのコピーが必要な場合は、値で受け入れて移動します
  • 入力パラメータを変更する必要がある場合は、入力参照を受け入れます。しかし、多くの場合、パラメーターを値で取得してコピーを返すことを好みます。
  • out パラメータは避けます。値による返品は安価であり、常に推奨されます。
  • 参照と const 参照を使用して、ローカル エイリアスを作成しています。
  • 右辺値参照は避けます

テキストの塊よりも少しのコードの方が優れています:

void f(const Foo &); // input parameter
void f(Foo); // input parameter, modified or sinked
void f(Foo &); // input-output
Foo f(); // output

少なくともインターフェイスでは、ポインターを使用しないようにしています。ポインターは所有していない必要がありますが、実際には、C とレガシー コードが多すぎて、これに該当しません。ポインターが表示されると、所有権と一生。所有しているポインターを魔法のように取り除くことはできないため、私は常にそうします。

これらは一般的なアドバイスであり、インターフェイスでそれらに従うことをお勧めします。それ以外の場合は、自己責任で冒険し、適切な判断を下してください!

オプションの参照が必要な場合はどうすればよいですか?

可能であればデフォルトのパラメータを使用し、必要であればポインタを使用してください。

242 当然の答えでしょうが、残念ながら委員会が標準化を拒否しているのは主に、代入と比較が何をすべきかについて合意できないためです。しかし答えは非常に単純です。これらの操作は提供されるべきではありません。 理由はわかりませんが、多くの人は、意味をなさない場合や混乱を招く場合に、すべての演算子を提供せざるを得ないようです。適切なデフォルトがない場合は、デフォルトを提供しようとしないでください

特殊化せずにオプションで参照をサポートする方法は次のとおりです。

template<class T>
 class optional {
 public:
 [[deprecated]] template<class U = T>
 requires std::semiregular<T>
 optional& operator=(U&&);
 };

template<class T, class U>
requires (std::regular<T> && std::regular<U>)
constexpr bool operator==(const optional<T>&, const optional<U>&);

これは目新しいことではありません。ラッパー オブジェクトは、ラップされた型よりも多くの規則性を公開しようとしないでください。

255 を削除しました そして、当然のことながら、誰もそれを見逃すことはありません.特定の操作が何をすべきかについての果てしない、解決できない議論の代わりに、より良い質問は:その操作は有用ですか?ここでの答えはノーです。使用法を見てください。

これは、参照はほとんどの場合、戻り値とパラメーターとして有用であるという Herb Sutter の主張と一致しています。

not_null、object_ptr、observer_ptr などはどうですか?

269 構築により有効です。ポインターを使用しない限り、273 を誤用する唯一の方法 関与していない間は従うことです。

ポインターから構築された型は、参照中と構築中の 2 倍の機会を与えてくれます。コンパイル時エラーを実行時エラーにシフトしています…進むべき正しい方向ではありません!さらに、282 290 のような便利な機能を提供します 、 306317

参照は単なるポインターですか?

メモリアドレスはずっ​​と下にありますが、参照がどのように実装されているかは問題ではありません。これらは null ではなく再バインドできないため、エイリアスとして動作し、エイリアス オブジェクトの有効期間に関連付けられます。