これは三項演算子の合理的な使用法ですか?[閉まっている]
質問
次のようなコードに起因する理解/保守性の問題はありますか?
inVar1 == 0 ? NULL : v.push_back(inVar1);
inVar2 == 0 ? NULL : v.push_back(inVar2);
など。
おそらく混乱を招くアイデアは、プログラム フローに変数の代入ではなく三項演算子を使用することです (これは通常の説明です)。
この使用法に対処するコーディング標準を見たことがありません。そのため、これを行うことに抵抗はありませんが、そうしない正当な理由があるかどうかを知りたいと思っています。
解決
私はそれが混乱し、単純に入力するよりも読み多くの困難だと思います。
if (inVar != 0)
v.push_back(inVar);
私は結果がどんな確信を持ってどうなるかを把握するためにあなたの例を数回スキャンする必要がありました。あなたの例よりも(){}文があれば私もシングルラインを好むだろう - と私はシングルラインを憎むif文:)
他のヒント
三オペレータは、値を返すことを意味する。
IMO、それは状態を変異させてはならない、および戻り値が使用されるべきである。
は、他のケースでは、if文を使用します。文は、コード圏を実行することを意図している場合。
三元は良いことであり、私は一般的に、それは使い方だ促進します。
あなたがここでやっていることはしかし、それは信頼性だ変色します。それはそう、短いですが、それは不必要に複雑だ。
私は、これは避けるべきだと思います。声明場合は、その場所に1行を使用することができます。
if(inVar1 != 0) v.push_back(inVar1);
これらの日は三項演算子としてかのように速くなりますコンパイラます。
あなたの目標は、読むために、他のソフトウェア開発者のためにそれをいかに簡単である必要があります。
私は
に投票しますif ( inVar != 0 )
{
v.push_back( inVar );
}
なぜかっこ...ある日、あなたはそこに何かを置きたいこととブラケットはあなたのために事前に行われているため。ほとんどの編集者、これらの日は、とにかくに入れます。
三項演算子を使用しても何も得られず、コードの可読性が損なわれます。
三項演算子は使用していない値を返すため、奇妙なコードです。の使用 if
あなたのようなケースでは、より明確になります。
コメント欄で述べた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);
、私が提供したいと思います(読むとき、あなたはその副作用のための式をスキャンする余分な作業をしなければならない)
!inVar1 ?: v.push_back(inVar1);
!inVar2 ?: v.push_back(inVar2);
あなたがあいまいなために行っている場合は、 ...、それはです。 GCCはx ?: y
の代わりにx ? x : y
することができます。 : - )
私は条件付き引数を持ついくつかの関数を呼び出す必要があるとき、私は三項演算子を使用 - 。この場合には、それは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());
私は、前者がより魅力的です見つけます。あなたは2ほぼ同じを記述する必要はありません - そしてそれは、後者とは異なり、 DRY の原則に準拠します行ます。
私はあなたがより良い構造であれば適切に行うことで楽しむことだと思います。私も構造が、イベントに私は条件付き実行に後で行を追加する必要があればいつも私とブレースを持っていることを好むます。
if (inVar != 0) {
v.push_back(inVar);
}
私は時々三元は、コンストラクタの初期化子リストで必要悪だと思います。私はほとんど私がメモリを割り当てると、コンストラクタの本体の前にそれを指すようにいくつかのポインタを設定するコンストラクタのためにそれらを使用します。
たとえば、あなたが入力としてベクトルを取る持っていると思った整数のストレージ・クラスを持っていたが、内部表現が配列であると仮定します:
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
}
これは私が三項演算子を使用する方法です。私は何人かの人々がそうであるように、混乱を招くものであるとは思わないが、私は1つが、彼らはそれを使用してどのくらいに制限すべきであるということだと思います。
たとえばます:
if (inVar1 != 0)
v.push_back(inVar1);
if (inVar2 != 0)
v.push_back(inVar2);
はv.push_backが無効であると仮定して動作しますが、それは別の関数に渡される必要がある値を返す何か?その場合には、このような何かを見ているでしょう。
SomeType st;
if (inVar1 != 0)
st = v.push_back(inVar1);
else if (inVar2 != 0)
st = v.push_back(inVar2);
SomeFunc(st);
しかし、それはコードのような単純な作品のために消化するより多くのです。私の解決策:別の関数を定義します。
。SomeType GetST(V v, int inVar1, int inVar2){
if (inVar1 != 0)
return v.push_back(inVar1);
if (inVar2 != 0)
return v.push_back(inVar2);
}
//elsewhere
SomeFunc(GetST(V v, inVar1, inVar2));
いずれにしても、ポイントはこれです:あなたはあまりにも三元のために拷問を受けていますいくつかのロジックを持っていますが、それはif文、どこか別の場所にそれを置く。
に入れていた場合、あなたのコードを乱雑になる場合!inVar1 != 0 || v.push_back(inVar1);
inVar2 != 0 || v.push_back(inVar2);
Perlのような言語で見つかった一般的なパターンます。
あなたは、1つまたはtenary引数の両方にその間違ったで複数のメソッド呼び出しを持っている場合。関係なく、どのような文のコードのすべての行が短く、シンプルである必要があり、理想的に配合ません。
、適切に他の人が言及したようステートメントは、より読みやすい場合。デバッガを使用してコードをステップ実行しているときにも、すべてが1行のときに取られている場合は、容易にどの枝を表示することはできませんか、あなたは三式を使用している:
if (cond) doIt();
cond ? noop() : doIt();
以下は、(あなたが中括弧があるかどうかに関係なく)を介してのステップに非常に良くあるのに対し
if (cond) {
doIt();
}
、それが1行より短いか明確ではありません。しかし、それはまた、もはやません - と、本当に完全に理解することは困難ではありません。あなたは三項演算子を知っていれば、それは何が起こっているのかは明らかだ。
すべての後、私はそれが変数に代入されていたならば、誰もが(それは同様の状態を変異された場合でも)問題を抱えているとは思わない:
var2 = inVar1 == 0 ? NULL : v.push_back(inVar1);
三オペレータは常に値を返すという事実 - IMO - 無関係です。あなたはすべての戻り値を使用するという要件は確かにありません...結局、割り当ては値を返します。
私はNULLの枝と一緒に渡って実行した場合、言われていること、私はif文に置き換えると思います。
でもの、それは3ラインを交換した場合if文ます:
if (inVar == 0) {
v.doThingOne(1);
} else {
v.doThingTwo(2);
}
と
invar1 == 0 ? v.doThingOne(1) : v.doThingTwo(2);
私はをはそれを残すかもしれない...私の気分に応じて。 ;)