3

私は最近、この質問への回答として次のコード ブロックを見ました: C++ で文字列を分割しますか?

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string>     
&elems) {
    std::stringstream ss(s);
    std::string item;
    while(std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

参照渡しの配列「elems」を返すことがここで重要なのはなぜですか? これを void 関数にするか、整数を返して成功/失敗を示すことはできませんか? とにかく実際の配列を編集していますよね?

ありがとうございました!

4

2 に答える 2

6

渡したオブジェクトへの参照を返すことで、1 つの式でいくつかのチェーンまたはカスケードを実行し、同じベクターをずっと操作できます。一部の人々は、これが便利だと思います: IE

  std::vector<std::string> elems;
  std::cout << "Number of items:" << split("foo.cat.dog", '.', elems).size();

  // get just foo
  std::cout << "First item is:" << split("foo.cat.dog", '.', elems)[0];

  // change first item to bar
  split("foo.cat.dog", '.', elems)[0] = "bar";
于 2012-07-18T17:56:32.877 に答える
1

メモリアドレスを返していません。実際には、非定数参照によってオブジェクトを返しています。渡されたのと同じ方法です。呼び出し元のコードは、関数からの戻り時に入力される3番目のパラメーター、またはreturnパラメーターのいずれかに依存する可能性があるため、これは少しやり過ぎに思えるかもしれません。

このようにする理由は、連鎖を許可するためです。だからあなたはすることができます:

split(myString, ',', asAVector).size().

sizeこれは関数を実行し、ベクトル(この場合)で関数を呼び出すことによって結果を連鎖させることができます

きちんとしたものにもかかわらず、このアプローチにはいくつかの潜在的な欠点があります。たとえば、戻り値にエラーコードが存在しないため、正常に動作するか例外をスローする関数に依存します。tryしたがって、通常は上記を/catchセマンティクスでラップすることを期待します。もちろん、連鎖を増やすほど、さまざまなタイプの例外の可能性が高くなる可能性が高くなるため、より多くのcatchブロックをカバーする必要があります。

念のために言っておきますが、参照によるパスバックは、ポインターによるパスバックよりもはるかに優れています。ポインタを使用したチェーンは、チェーン内の関数の1つが失敗して0を返すと判断した場合にクラッシュすることで有名です。

于 2012-07-18T18:25:32.980 に答える