3

関数がパラメーターを処理する必要があるのはその値を確認することだけである場合、そのパラメーターを常に定数参照で渡す必要はありませんか?

私の同僚は、小さい型では問題ないと言いましたが、私は同意しません。

これを行う利点はありますか:

void function(char const& ch){ //<- const ref
    if (ch == 'a'){
        DoSomething(ch);
    }
    return;
}

これについて:

void function(char ch){ //<- value
    if (ch == 'a'){
        DoSomething(ch);
    }
    return;
}

それらは私には同じサイズに見えます:

#include <iostream>
#include <cstdlib>

int main(){

    char ch;
    char& chref = ch;

    std::cout << sizeof(ch) << std::endl; //1
    std::cout << sizeof(chref) << std::endl; //1

    return EXIT_SUCCESS;
}

しかし、これが常に当てはまるかどうかはわかりません。
追加のオーバーヘッドが発生せず、自己文書化されているため、私は正しいと思います。
しかし、私の推論と仮定が正しいかどうかコミュニティに尋ねたいですか?

4

5 に答える 5

3

あなたの同僚は正しいです。小さな型 (char、int) の場合、変数が変更されない場合、参照渡しは意味がありません。ポインターのサイズ (参照渡しの場合に使用) は小さな型のサイズとほぼ同じであるため、値渡しの方が適しています。

さらに、値渡しはタイピングが少なくて済み、読みやすくなります。

于 2012-04-21T04:47:09.620 に答える
2

sizeof(chref)は と同じですが、文字sizeof(ch)を参照渡しすると、ほとんどのシステムでより多くのバイトが必要になります。標準では参照の実装について具体的なことは何も述べていませんが、アドレス (つまりポインタ) は定期的に舞台裏で渡されます。最適化をオンにすると、おそらく問題になりません。テンプレート関数をコーディングする場合、変更されない不明な型の項目は、常に const 参照によって渡される必要があります。

小さな型に関する限りconst、関数のシグネチャを介して引数に触れないという点を強調するために、修飾子を使用して値で渡すことができます。

void function(const char ch){ //<- value
    if (ch == 'a'){
        DoSomething(ch);
    }
    return;
}
于 2012-04-21T04:10:46.817 に答える
2

値が小さい場合、参照を作成して逆参照するコストは、コピーするコストよりも大きくなる可能性があります (違いがある場合)。これは、参照パラメーターがほぼ常にポインターとして実装されていると考える場合に特に当てはまります。値を次のように宣言するだけで、どちらも同様に適切に文書化されますconst(この値は入力のみに使用しており、変更されません)。私は通常、すべての標準の組み込み型をconst値で作成し、すべてのユーザー定義/STL型を として作成しconst &ます。

の単なるエイリアスであるため、あなたのsizeof例には欠陥があります。どのタイプでも同じ結果が得られます。chrefchsizeof(T)T

于 2012-04-21T04:35:22.097 に答える
1

サイズは渡されたものと同じではありません。結果は ABI の呼び出し規約によって異なりますが、 は sizeof(referenceVariable)を生成しsizeof(value)ます。

関数がパラメーターを処理する必要があるのはその値を確認することだけである場合、そのパラメーターを常に定数参照で渡す必要はありませんか?

それががすることです。私は人々が私に同意しないことを知っており、小さなビルトインを値で渡すことを主張したり、const. 参照渡しは、命令を追加したり、より多くのスペースを消費したりする可能性があります。私は一貫性のためにこの方法を渡します。これは、特定のプラットフォームに最適な方法を常に測定することは、維持するのに非常に手間がかかるためです。

読みやすさ以外に利点はありません (それが好みの場合)。パフォーマンスがわずかに低下する可能性がありますが、ほとんどの場合、考慮に入れる必要はありません。

これらの小さなビルトインを値で渡す方が一般的です。値渡しの場合constは、(宣言とは関係なく) 定義を修飾できます。

私が推奨するのは、大多数のチームは単に 1 つの方法を選択してそれを使い続けることであり、すべての指示が重要でない限り、パフォーマンスがそれに影響を与えるべきではないということです。const決して痛くありません。

于 2012-04-21T04:13:04.077 に答える
0

私の意見では、const 参照で渡す一般的なアプローチは良い方法です (ただし、例の注意事項については以下を参照してください)。一方、あなたの友人は、組み込み型の場合、参照渡しによってパフォーマンスが大幅に向上することはなく、パフォーマンスがわずかに低下する可能性さえあるということは正しいです。私は C のバックグラウンドを持っているので、ポインタの観点から参照を考える傾向があり (多少の違いはありますが)、「char*」は、私が使用しているどのプラットフォームでも「char」よりも大きくなります。見慣れた。

[編集: 誤った情報を削除しました。]

私の意見では、より大きなユーザー定義型を渡し、呼び出された関数が値を変更せずに値を読み取るだけでよい場合は、「type const&」で渡すのが良い方法です。あなたが言うように、それは自己文書化されており、内部 API のさまざまな部分の役割を明確にするのに役立ちます。

于 2012-04-21T04:27:13.070 に答える