web-dev-qa-db-ja.com

ベクトルの要素を(値によって、参照によって)変更する関数C ++

ベクトルの値を変更する必要がある関数があります。 C++でベクターを返すのは良い習慣ですか?

機能1:

vector<string> RemoveSpecialCharacters(vector<string> words)
{
    for (vector<string>::iterator it=words.begin(); it!=words.end(); )
    {
        if(CheckLength(*it) == false)
        {
            it = words.erase(it);
        }
        else{
            ++it;
        }
    }//end for

    return words;
}

関数2:

void RemoveSpecialCharacters(vector<string> & words)
{
    for (vector<string>::iterator it=words.begin(); it!=words.end(); )
    {
        if(CheckLength(*it) == false)
        {
            it = words.erase(it);
        }
        else{
            ++it;
        }
    }//end for
}
15
Hani Goc

2つの関数は、2つの異なる目的に役立ちます。

  • 機能1:remove_copyとして機能します。 notは既存のコンテナを変更します。代わりにコピーを作成して変更します。

  • 機能2:removeとして機能します。既存のコンテナを変更します。

6
billz

それはやや主観的です。私は個人的には後者を好みます。ベクターを呼び出し元にコピーするコストがかからないからです(ただし、呼び出し元は自由にコピーを作成できます)。

3
NPE

この特定のケースでは、参照渡しを選択しますが、それはC++の慣習であるかどうかではなく、実際に意味があるためです(その名前の関数はベクトルに変更を適用します)。関数からデータを返す実際のneedはないようです。

しかし、それは関数の目的にも依存します。 alwaysを次のように使用したい場合:

vec = bow.RemoveSpecialCharacters(vec);

次に、絶対に最初のオプションは行くことです。それ以外の場合は、2番目の方が適切と思われます。 (関数名から判断すると、最初のものは私にとっての方が適切と思われます)。

パフォーマンスの点では、現代のC++ 11の世界での最初のソリューションは、いくつかの割り当てが遅くなるため、パフォーマンスへの影響は無視できます。

2
Spook

オプション2に移動し、パラメーターとして渡されるベクトルを変更します。

補足事項:一部のコーディング慣行では、変更される可能性のあるポインタ引数を渡すことを推奨しています(開発者に一目でわかるように、関数が引数を変更する場合があります)。

1
Claudio

ベストプラクティスは、ベクターを参照渡しすることです。

関数内で編集し、戻す必要はありません(実際には、不要な新しいメモリ空間を割り当てています)。

参照渡しする場合、コストははるかに小さく、ベクトルも関数のスコープ外で編集されます

1
EoD

最初の関数はベクトルのコピーを返すため、2番目の関数よりも遅くなります。 2番目を使用する必要があります。

実際のところ、C++ライブラリでそれがどのように行われるかを意味するのが良い習慣である場合、どちらもC++の良い習慣ではありません。あなたは基本的に何を再実装しますstd::remove_copy_ifまたはstd::remove_ifはそうするので、値または参照によって、コンテナではなく範囲で機能する関数を実装する(または既存の関数を使用する)ことをお勧めします。

繰り返しますが、これはgood practice

0
Slava