2016-03-21 4 views
2

ich diese Funktion Erklärung haben:Um kein Argument aufgrund einer Bedingung passieren

void do_somthing(int a,int b,foo bar = foo()); 

Ich möchte für einige Argumente wie folgt nennen:

foo bar = get_bar_by_some_algorithm(); 
int a = 5,b = 6; 
if(bar.empty()){ 
    do_somthing(a,b); 
} 
else{ 
    do_somthing(a,b,bar); 
} 

Ich möchte von der loswerden if Aussage. Also, ich habe es wie folgt aus:

foo bar = get_bar_by_some_algorithm(); 
int a = 5,b = 6; 
do_somthing(a,b,bar.empty()?foo():bar); 

aber mein Ansatz akzeptabel ist (ist es gut, auch?), Wenn do_somthing stabil ist aus Standardargument Sicht aber wenn es geändert, um etwas wie folgt aus:

void do_somthing(int a,int b,foo bar = get_special_foo()); 

Mein Code wird veraltet, weil foo() nicht gleich get_special_foo() ist.

Die Frage ist, wie kann ich ? Operator oder ein beliebiges kurzes Äquivalent verwenden, um ein Argument im Falle von nicht leer übergeben und nicht alles im Falle leer?

Beispiel zur Verdeutlichung (Imaginary Syntax):

do_somthing(a,b,bar.empty()? the_default_argument : bar); 
+1

Beide ternären Operator und 'if' würde einen Zweig tun, BTW. – Jarod42

+1

Sie können einfach "bar" übergeben und das 'if (bar.empty())' checken Sie in 'do_somthing' ein. – CompuChip

+0

versuchen boost :: optional – Thomas

Antwort

2

Ihr Ansatz mit dem ternären Operator war in Ordnung, aber es schien nicht notwendig. Es ist nicht normal, zu einem späteren Zeitpunkt neue Standardwerte für Funktionen einzufügen, ohne die Konsequenzen zu berücksichtigen. Wenn Ihr Standardwert nicht aussagekräftig ist, stimmt etwas mit Ihrem Design überhaupt nicht.

Aber nur um Sie zu unterhalten, hier ist eine Zweiglose Version. I könnte so etwas in Betracht ziehen, wenn mein Hauptanliegen ein gemessener Engpass aufgrund von Verzweigungsfehlvorhersage war. Ich würde dies normalerweise nicht tun, denn es ist weniger klar als eine einfache if-Anweisung:

static auto do_something[2] = { 
    +[](int a, int b, foo bar) { do_something(a, b, bar); }, 
    +[](int a, int b, foo bar) { do_something(a, b); } 
}; 
do_something[bar.empty()](a, b, bar); 
+0

Sie handeln Verzweigungsvorhersage zu Sprungvorhersage. – Jarod42

+0

Nein, denn der Compiler sollte das Lambda zu einem reinen Funktionsaufruf machen, was sowieso passieren würde. In jedem Fall war es nur eine Illustration. – paddy

1

Die kurze Antwort ist, dass Sie nicht ?: dafür verwenden können.

Die Spezifikation des ternären Operators ?: erfordert, dass alle drei Operanden gültige Ausdrücke sind. Ein gültiger Ausdruck (übermäßig vereinfacht) ist ein Konstrukt, das einen oder mehrere Werte auswertet, (optional) auf die Werte einwirkt, die Operatoren verwenden, und ein Ergebnis erzeugt.

Ein Ausdruck mit nichts darin ist ein Widerspruch: Er bewertet nichts, kann also kein Operand des Operators ?: sein.

Hinweis: Es ist möglich, eine leere Anweisung zu haben (z. B. durch eine isolierte ;). Aber eine leere Aussage ist kein Ausdruck.

Die offensichtliche Lösung, um die if() weg zu verstecken wäre, den Test innerhalb Ihrer Funktion zu tun, wie in den Kommentaren von CompuChip erwähnt. Oder schreiben Sie eine Wrapper-Funktion, die den Test für Sie durchführt (und stellen Sie sicher, dass Ihre do_somthing() in keiner anderen Kompilierungseinheit deklariert ist, um die Versuchung zu vermeiden, sie direkt anstatt des Wrappers aufzurufen).

Verwandte Themen