7

次のようなコードに起因する理解/保守性の問題はありますか?

inVar1 == 0 ? NULL : v.push_back(inVar1);
inVar2 == 0 ? NULL : v.push_back(inVar2);

など。

混乱する可能性のあるアイデアは、通常の説明である変数代入ではなく、プログラム フローに三項演算子を使用することです。

この使用法に対処するコーディング標準が機能しているのを見たことがないので、これを快適に行うことができる一方で、そうしない正当な理由があるかどうかを知りたい.

4

16 に答える 16

35

単純に入力するよりもわかりにくく、読むのがずっと難しいと思います。

if (inVar != 0)
  v.push_back(inVar);

結果がどうなるかを確実に把握するために、あなたの例を数回スキャンする必要がありました。私はあなたの例よりも単一行の if() {} ステートメントを好むでしょう-そして、単一行の if ステートメントは嫌いです:)

于 2009-02-07T01:41:35.580 に答える
25

三項演算子は値を返すためのものです。

IMO、状態を変更してはならず、戻り値を使用する必要があります。

それ以外の場合は、if ステートメントを使用します。if ステートメントは、コード ブロックを実行するためのものです。

于 2009-02-07T01:44:40.333 に答える
11

三項は良いことであり、私は一般的にその使用を促進します。

しかし、あなたがここでしていることは、その信頼性を傷つけます。確かに短いですが、不必要に複雑です。

于 2009-02-07T02:53:33.283 に答える
10

これは避けるべきだと思います。その代わりに 1 行の if ステートメントを使用できます。

if(inVar1 != 0) v.push_back(inVar1);
于 2009-02-07T01:41:26.813 に答える
6

最近のコンパイラは、if を三項演算子と同じくらい高速に作成します。

目標は、他のソフトウェア開発者がどれだけ読みやすいかということです。

に投票します

if ( inVar != 0 )
{
   v.push_back( inVar );
}

なぜ括弧があるのか​​...ある日、そこに何か他のものを入れたいと思うかもしれません。括弧はあらかじめ用意されています。最近のほとんどの編集者はとにかくそれらを入れます。

于 2009-02-07T02:34:59.640 に答える
6

三項演算子を使用しても何も得られず、コードの読みやすさが損なわれます。

三項演算子は使用していない値を返すため、それは奇数コードです。あなたのようなケースでは、 an の使用はifより明確です。

于 2009-02-07T02:48:23.200 に答える
5

コメントで litb が述べたように、これは有効な C++ ではありません。たとえば、GCC は次のコードでエラーを出力します。

error: `(&v)->std::vector<_Tp, _Alloc>::push_back [with _Tp = int, _Alloc =
std::allocator<int>](((const int&)((const int*)(&inVar1))))' has type `void' 
and is not a throw-expression

ただし、キャストすることで回避できます。

inVar1 == 0 ? (void)0 : v.push_back(inVar1);
inVar2 == 0 ? (void)0 : v.push_back(inVar2);

しかし、どのくらいの費用がかかりますか?そして、何の目的で?

ここで三項演算子を使用すると、この状況で if ステートメントよりも簡潔になるわけではありません。

inVar1 == 0 ? NULL : v.push_back(inVar1);
if(inVar1 != 0) v.push_back(inVar1);
于 2009-02-07T03:38:26.313 に答える
2

条件付き引数を使用して関数を呼び出す必要がある場合は、三項演算子を使用します。この場合は、それよりも優れていifます。

比較:

printf("%s while executing SQL: %s",
        is_sql_err() ? "Error" : "Warning", sql_msg());

if (is_sql_err())
    printf("Error while executing SQL: %s", sql_msg());
else
    printf("Warning while executing SQL: %s", sql_msg());

前者の方が魅力的だと思います。また、後者とは異なり、 DRYの原則に準拠しています。2 つのほぼ同一の行を記述する必要はありません。

于 2009-02-07T07:39:50.787 に答える
2

実際には、この種の書き方を思いとどまらせる人々の意見には同意しますが (読むときは、式の副作用をスキャンするために余分な作業を行う必要があります)、私は提供したいと思います。

!inVar1 ?: v.push_back(inVar1);
!inVar2 ?: v.push_back(inVar2);

...あいまいにする場合は、それです。GCC はx ?: yの代わりに許可しますx ? x : y。:-)

于 2009-02-07T02:39:55.527 に答える
1

コンストラクターの初期化子リストでは、三項が必要悪である場合があると思います。私は主に、メモリを割り当てたいコンストラクタに使用し、コンストラクタの本体の前にそれを指すポインタを設定します。

例として、入力としてベクトルを取りたいが、内部表現が配列である整数ストレージ クラスがあるとします。

class foo
{
public:
    foo(std::vector<int> input);
private:
    int* array;
    unsigned int size;
};

foo:foo(std::vector<int> input):size(input.size()), array( (input.size()==0)?
        NULL : new int[input.size])
{
    //code to copy elements and do other start up goes here
}

これが三項演算子の使い方です。一部の人ほど混乱しているとは思いませんが、使用量を制限する必要があると思います.

于 2009-02-07T21:52:23.670 に答える
1

適切なif構造を行う方が良いと思います。後で条件付き実行に行を追加する必要がある場合に備えて、if 構造に常に中かっこを付けることを好みます。

if (inVar != 0) {
    v.push_back(inVar);
}
于 2009-02-07T01:44:48.710 に答える
0

10 項引数の 1 つまたは両方に複数のメソッド呼び出しがある場合、それは間違っています。どのステートメントに関係なく、コードのすべての行は短くて単純である必要があり、理想的には複合化されていません。

于 2009-02-07T07:50:35.587 に答える
0

他の人が述べたように、適切な if ステートメントの方が読みやすいです。また、デバッガーを使用してコードをステップ実行する場合、すべてが 1 行に収まっている場合や三項式を使用している場合、if のどの分岐が行われるかをすぐに確認することはできません。

if (cond) doIt();

cond ? noop() : doIt();

一方、以下はステップスルーする方がはるかに優れています(ブレースがあるかどうかに関係なく):

if (cond) {
    doIt();
}
于 2009-02-07T07:50:54.663 に答える