0

最近、プログラムの仕事の面接に行ったところ、ベクトルと整数をパラメーターとして受け取る関数を書くように言われました。タスクは、整数より上、下、または等しいベクトル内の要素の数をカウントすることでした。私はこれらの行に沿って何かを書きました:

void printStat(const std::vector<int> &vec, const int &val)
{
    int results[3] = {0,0,0};
    for (int i = 0; i < vec.size(); ++i) {
        int option = (vec[i] == val) ? 0 : ((vec[i] > val) ? 1 : 2);
        results[option]++;
    }
    ...
}

彼らは、私が疑わしいと思ったコードについていくつかのコメントをしました。C++ の専門家の意見を知りたいです。彼らは、値渡しvecval参照渡しは値渡しよりも効率が悪いと言いました。次のように書いたほうがよかったでしょう。

void printStat(const std::vector<int> vec, const int val) {}

正直なところ、私は常に最初のバージョン (一番上) を使用してコードを書いてきましたが、なぜ私の方法が彼らの方法よりも優れているのか、または違いがないのかを説明する議論はありませんでした。彼らの主張は、参照によって引数を渡すと、後でその内容が必要なときに変数を逆参照するように強制されるというものでした。これは、変数を値で渡した場合よりも遅くなります。

私の質問は次のとおりです。最善の方法は何ですか?また、その理由は何ですか?

[]おまけの質問: 彼らはまた、ループ内で反復子を使用する方が、ベクトルの要素にアクセスするために演算子を使用するよりも効率的であると主張しました。vec[i]特に、 5行目で2回アクセスするとL1キャッシュにあると思われるため、これには理由がありません。

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

4

3 に答える 3

4

それはあなたがどのように使用するかによって異なりますvec。ベクトルに多くのエントリがない場合は、コピーが非常に高速になるため、値で渡しても問題ありません。しかし、一般的には参照渡しの方が「効果的」です。

val一方、ネイティブ型の場合、通常、それらを定数参照として渡す必要はありません。実際、参照は内部でポインターとして実装されることが多いため (常にではないにしても)、このパラメーターを参照として渡すと、64 ビット マシンでは、plain の 32 ビット値と比較して 64 ビット値が渡されますint。これはポインターであるため、追加の間接参照も使用されます。

于 2013-10-29T13:04:06.880 に答える
1

const参照でオブジェクトを渡すことに固執します。例外は、とにかくコピーが作成された場合です (const T は、関数の実装での偶発的な変更を防ぐ以外に意味がありません)。

ただし、実装方法を変更しましたoperator =

T& operator=(const T& other) {
   T(other).swap(*this);
   return *this;
}

T& operator=(T other) {
   other.swap(*this);
   return *this;
}

コピーの省略と移動のセマンティクスを許可します。

于 2013-10-29T13:21:05.837 に答える