Frage

Gibt es irgendwelche Verständnis-/Wartbarkeitsprobleme, die sich aus Code-ähnlichem Code ergeben?

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

und so weiter.

Die möglicherweise verwirrende Idee besteht darin, den ternären Operator für den Programmablauf zu verwenden und nicht für die Variablenzuweisung, was die übliche Erklärung ist.

Ich habe keine funktionierenden Codierungsstandards gesehen, die sich mit dieser Verwendung befassen. Obwohl ich damit kein Problem habe, würde ich gerne herausfinden, ob es einen guten Grund gibt, dies nicht zu tun.

War es hilfreich?

Lösung

Ich denke, es ist verwirrend und viel schwieriger zu lesen als nur die Eingabe;

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

Ich hatte Ihr Beispiel mehrmals scannen, um herauszufinden, was das Ergebnis mit Sicherheit wäre. Ich würde sogar ein einzeiliges vorziehen, wenn () {} Anweisung als Ihr Beispiel - und ich einzeilige if-Anweisungen hassen:)

Andere Tipps

Der ternäre Operator soll einen Wert zurück.

IMO, sollte es nicht Zustand mutieren, und der Rückgabewert verwendet werden.

Im anderen Fall verwenden, wenn Aussagen. Wenn Aussagen gemeint Codeblöcke auszuführen.

Die ternäre ist eine gute Sache, und ich fördern in der Regel ist es Nutzung.

Was Sie tun hier jedoch trübt es Glaubwürdigkeit ist. Es ist kürzer, ja, aber es ist unnötig kompliziert.

Ich denke, das sollte vermieden werden. Sie könnten eine 1-line if-Anweisung an seiner Stelle verwendet werden.

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

Compiler in diesen Tage werden ein, wenn so schnell wie ein ternärer Operator machen.

Sie Ziel sollte sein, wie einfach es ist, für eine andere Software-Entwickler zu lesen.

Ich stimme für

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

, warum die Klammern ... denn eines Tages möchten Sie vielleicht etwas anderes dort setzen und die Halterungen sind für Sie vorge getan. Die meisten Redakteure in diesen Tagen werden sie in irgendeiner Weise setzen.

Ihre Nutzung des ternären Operator gewinnt man nichts und Sie verletzen die Codes Lesbarkeit.

Da der ternäre Operator einen Wert zurückgibt, die Sie nicht verwenden, es ungerade Code ist. Die Verwendung eines if ist viel klarer in einem Fall wie bei Ihnen.

Wie bereits in den Kommentaren erwähnt, ist dies ist kein gültiges C++.GCC gibt beispielsweise bei diesem Code einen Fehler aus:

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

Dies kann jedoch durch Casting umgangen werden:

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

Aber zu welchen Kosten?Und zu welchem ​​Zweck?

Es ist nicht so, dass die Verwendung des ternären Operators hier prägnanter wäre als eine if-Anweisung in dieser Situation:

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

Während in der Praxis ich mit den Gefühlen die zustimmen, die diese Art des Schreibens entmutigen (beim Lesen, Sie haben zusätzliche Arbeit zu tun, den Ausdruck für seine Nebenwirkungen scannen), ich mag bieten

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

... wenn Sie für obskures gehen, das ist. GCC ermöglicht x ?: y anstelle von x ? x : y. : -)

ich ternären Operator verwenden, wenn ich eine Funktion mit bedingten Argumenten müssen nennen -. In diesem Fall ist es besser, dann if

vergleichen:

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

mit

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

Ich finde die ehemalige attraktiver ist. Und es entspricht href="http://en.wikipedia.org/wiki/DRY" rel="nofollow noreferrer"> DRY Prinzip

Ich glaube, Sie besser gedient wäre, wenn Struktur eine richtige dabei. Ich ziehe es auch immer Klammern mit meinen, wenn Strukturen müssen in dem Fall, ich habe Leitungen an die bedingte Ausführung später hinzuzufügen.

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

Ich denke, dass manchmal die ternäre ein notwendiges Übel in initializer Listen für Bauherren sind. Ich benutze sie hauptsächlich für den Bau, wo ich will Speicher zuweisen und einige Zeiger auf Punkt, an mich vor dem Körper des Konstruktor festgelegt.

Ein Beispiel: Angenommen, Sie eine ganze Zahl Speicherklasse hatte, dass Sie einen Vektor als eine Eingabe aber die interne Darstellung ist ein Array nehmen haben wollte:

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
}

Das ist, wie ich den ternären Operator verwenden. Ich glaube nicht, es so verwirrend ist, wie manche Leute tun, aber das glaube ich, dass man begrenzen, wie viel sie es verwenden.

Die meisten der gequälten Ternäre (wie ist das für Alliteration?) Ich sehe es versucht nur auf Logik setzen, die wirklich in einer if-Anweisung in einem Ort gehört, wo eine if-Anweisung gehört nicht oder kann nicht gehen.

Zum Beispiel:

if (inVar1 != 0)
  v.push_back(inVar1);
if (inVar2 != 0)
  v.push_back(inVar2);

arbeitet unter der Annahme, dass v.push_back ist ungültig, aber was ist, wenn es einen Wert hat Rückkehr, die an einem anderen Funktion erhalten geben muss? In diesem Fall wäre es so etwas wie folgt aussehen haben:

SomeType st;
if (inVar1 != 0)
  st = v.push_back(inVar1);
else if (inVar2 != 0)
  st = v.push_back(inVar2);
SomeFunc(st);

Aber das ist mehr für so ein einfaches Stück Code zu verdauen. Meine Lösung:. Definieren eine weitere Funktion

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));

Auf jeden Fall ist der Punkt: wenn Sie eine gewisse Logik, die für ein ternären zu gefoltert hat, aber wird Ihren Code vollstopfen, wenn es in einem setzen ist, wenn Aussage, es ausdrückte woanders

!
inVar1 != 0 || v.push_back(inVar1);
inVar2 != 0 || v.push_back(inVar2);

gemeinsames Muster in Sprachen wie Perl gefunden.

Wenn Sie mehrere Aufrufe von Prozeduren in einem oder beiden der tenary Argumente haben dann seine falsch. Alle Codezeilen unabhängig davon, welche Aussage sollten kurz sein und einfach, im Idealfall nicht verschlimmert.

Eine richtige if-Anweisung mehr lesbar ist, wie andere erwähnt haben. Auch, wenn Sie mit einem Debugger durch den Code sind Schritt, werden Sie nicht in der Lage sein, leicht, welchen Zweig eines zu sehen, ob genommen wird, wenn alles in einer Zeile ist oder Sie verwenden einen ternären Ausdruck:

if (cond) doIt();

cond ? noop() : doIt();

Während die folgende viel schöner ist, um durch (ob Sie die geschweiften Klammern haben oder nicht):

if (cond) {
    doIt();
}

Wie bereits erwähnt, ist es nicht kürzer oder klarer als eine 1 Zeile if-Anweisung. Allerdings ist es auch nicht mehr - und ist nicht wirklich so schwer zu grok. Wenn Sie den ternären Operator wissen, es ist ziemlich offensichtlich, was passiert.

Schließlich, ich glaube nicht, dass jemand ein Problem haben würde, wenn es zu einer Variablen zugewiesen wurde (auch wenn es wurde Zustand als auch mutiert):

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

Die Tatsache, dass der ternäre Operator immer einen Wert zurückgibt - IMO - ist irrelevant. Es ist sicherlich nicht erforderlich, dass Sie alle Rückgabewerte verwenden ... schließlich eine Zuordnung gibt einen Wert.

Dass gesagt wird, würde ich es mit einer if-Anweisung ersetzen, wenn ich auf sie mit einem NULL-Zweig lief.

Aber , wenn es ersetzt eine 3 Zeile if-Anweisung:

if (inVar == 0) {
   v.doThingOne(1);
} else {
   v.doThingTwo(2);
}

mit:

invar1 == 0 ? v.doThingOne(1) : v.doThingTwo(2);

I könnte es verlassen ... je nach Laune. ;)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top