web-dev-qa-db-ja.com

値または参照によるstd :: stringの受け渡し

可能性のある複製:
const std :: string&をパラメーターとして渡す日はありますか?

移動セマンティクスがサポートされている場合、std::stringを値または参照(インライン化されていない関数)で渡す必要がありますか?また、小さな文字列の最適化(SSO)を使用した実装についてはどうでしょうか?

72
Nordlöw

文字列で何をしているのかに基づいて、複数の回答があります。

1)IDとして文字列を使用します(変更されません)。 const参照で渡すことは、おそらくここでの最良のアイデアです:(std::string const&)

2)文字列を変更しますが、呼び出し側にその変更を見せたくない。値で渡すことをお勧めします:(std::string)

3)文字列を変更しますが、呼び出し元にその変更を確認させます。参照で渡すことをお勧めします:(std::string &)

4)関数に文字列を送信すると、関数の呼び出し元は文字列を二度と使用しません。 move Semantics を使用すると、オプション(std::string &&)になる場合があります

127
linuxuser27

C++ 11の場合はこの回答 を確認してください。基本的に、左辺値を右辺値参照に渡す場合

この記事 から:

void f1(String s) {
    vector<String> v;
    v.Push_back(std::move(s));
}
void f2(const String &s) {
    vector<String> v;
    v.Push_back(s);
}

「左辺値引数の場合、「f1」には値渡しであるため引数を渡すための余分なコピーが1つあり、「f2」にはPush_backを呼び出すための余分なコピーが1つあります。違いはありません。とにかく 'f1'または 'f2'に一時文字列を渡します。引数が一時(右辺値)の場合、 'f2'は移動ctorを利用できるため、引数は「f1」と「f2」で同じになりました。」

続き:「C++ 11では、次の場合に値渡しアプローチを使用することでパフォーマンスを向上させることができます。

  1. パラメータータイプは移動セマンティクスをサポートします-すべての標準ライブラリコンポーネントはC++ 11でサポートします
  2. 移動コンストラクターのコストは、コピーコンストラクターよりもはるかに安価です(時間とスタックの使用量の両方)。
  3. 関数内では、コピーと移動の両方をサポートする別の関数または操作にパラメータータイプが渡されます。
  4. 引数として一時を渡すのが一般的です-これを行うためにコードを整理できます。

OTOH、C++ 98の場合、参照渡しするのが最善です-コピーされるデータが少なくなります。 constまたはnon constを渡すことは、引数を変更する必要があるかどうかによって異なります。

19
emsr

通常の答えは、関数でコピーを作成する必要がある場合は、値渡しする必要があるということです。それ以外の場合はconst参照で渡します。

ここに良い議論があります: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

4
Vaughn Cato