2015-12-11 6 views
5

Im Wesentlichen das gleiche wie this question, aber für C++.Kann ich bedingt auswählen, welche Variable zugewiesen werden soll?

Der einfachste Weg, dies zu tun wäre:

if (condition) { 
    a = f(x); 
} else { 
    b = f(x); 
} 

Während dies meine Bedürfnisse erfüllt, hat es mich immer wieder wurde nervt, dass ich zweimal musste die Eingabe f (x) wiederholen, um nicht zu erwähnen erweitern der Code wird über so viele Zeilen ausgegeben, wenn nur eine Zeile ausgeführt wird. Was passiert, wenn ich eine größere Auswahl an Zielvariablen zur Auswahl habe?

switch(condition variable) { 
case 1: 
    var1 = f(x); 
    break; 
case 2: 
    var2 = f(x); 
    break; 
... 
case y: 
    vary = f(x); 
    break; 
} 

Das sieht sehr unelegant zu mir.

Gibt es irgendetwas in C++, das mir im Wesentlichen ermöglicht, Folgendes zu tun?

Verzeihen Sie, wenn es nicht ein Lvalue genannt wird, bin ich noch relativ neu in C++. Aber ihr wisst, was ich meine - die Zielvariable, der ein Wert zugewiesen werden soll.

+0

Sie können sicherlich eine Funktion schreiben, die einen Verweis zurückgibt und diesem zuweisen. –

+0

Wie mache ich das? Wie soll der Rückgabetyp der Funktion aussehen? – thegreatjedi

+0

Während es nicht die direkte Antwort auf die Frage ist, ist fval = f (x); if (Bedingung) a = fval; sonst ist b = fval' für mich viel lesbarer, während ich immer noch TROCKEN bin. – Amadan

Antwort

8

Sie können ein Formular Referenz oder ein Zeiger auf die Variable, die Sie zuweisen möchten.

(condition ? a : b) = f(x); // reference 

Die obige Version von aschepler in einem Kommentar vorgeschlagen wurde.

*(condition ? &a : &b) = f(x); // pointer 

Die Referenzversion entspricht im Wesentlichen dem folgenden ausführlicheren Beispiel mit einer Hilfsfunktion.

template <typename T> 
T& 
conditional_reference(bool pred, T& yes, T& no) noexcept 
{ 
    return pred ? yes : no; 
} 

// And then later 

conditional_reference(condition, a, b) = f(x); 

Mein Punkt ist, dass Ihr traditioneller if dann else Kontrollfluss wahrscheinlich in Form von Code Klarheit immer noch die beste Wahl ist.

Wenn die Quelle der Zuweisung ein komplexerer Ausdruck als nur f(x) ist, können Sie das Ergebnis in einer temporären Variablen speichern und diese Variable dann nur in Ihrer Bedingung zuweisen. Die C++ 11-Verschiebungssemantik macht die Verwendung solcher Provisorien in vielen Fällen akzeptabel.

+3

Wenn 'a' und' b' denselben Typ haben, dann wird plain old '(Bedingung? A: b) = f (x);'. – aschepler

+0

@aschepler Ehrlich gesagt, war ich ein wenig überrascht, dass das funktioniert, aber denke daran, sicher, es tut. Ich werde mich daran erinnern. – 5gon12eder

+0

Dies ist wahrscheinlich die genaue Lösung, nach der ich suche. Vielen Dank! Ich werde das als Antwort akzeptieren. – thegreatjedi

6

Wenn Sie können entscheiden, welche Variable bei der Kompilierung zuweisen, dann können Sie mit diesem sehr sauber und ohne Overhead Ansatz weg:

std::get<constexpr_indexer()>(std::tie(var1, var2, var3, var4)) = f(x); 

std::get, std::tie

+0

Danke für diese Antwort! Ich denke das ist besonders gut zu wissen, obwohl es leider nur auf Kompilierzeit beschränkt ist. Schade, ich kann nicht mehrere Antworten wählen. – thegreatjedi

2

Sie können eine Zeigervariable (z. B. double * p) in Ihrer switch-Anweisung zuweisen.

switch(condition variable) { 
case 1: 
    p = & var1; 
    break; 
case 2: 
    p = & var2; 
    break; 
... 
case y: 
    p = & vary; 
    break; 
} 

Dann können Sie dies tun, nachdem Sie Anweisung wechseln.

+0

Das löst das Problem nicht wirklich. Jetzt muss ich die switch-Anweisung mit der Zeigervariable auf der linken Seite machen. Es ist im Wesentlichen das Gleiche. Meine Frage ist, ob die switch-Anweisung vermieden werden kann und die gleiche Funktionalität in einer einzigen Zeile oder etwas in diesem Sinne zusammengefasst werden kann. – thegreatjedi

+0

@thegreatjedi können Sie den ternären Operator als 5gon12eder vorgeschlagen. Aber mehr noch, dass zwei Bedingungen und der Code unlesbar werden. –

0

Wie die Frage, die Sie verknüpft haben, haben Sie immer noch eine XY problem. Warum brauchst du das? Warum fühlst du mehr Code, der möglicherweise nicht lesbar und nicht mehr zu halten ist, weniger elegant als eine einfache if/else-Bedingung? Aber der Kern der Frage ist, in welchem ​​gültigen Szenario würden Sie (zusammen mit dem Alphabet) Variablen mit dem gleichen Wert haben?

Wenn Sie kein Szenario ähnlich der ursprünglichen Frage (Binary Search Tree) haben, bleiben Sie bei einer Variablen.

Bitte lesen DRY unrelated, but nearly identical, code:

Sie nicht trocken, weil jemand es in einem Buch irgendwo geschrieben, dass es gut ist zu tun, Sie DRY tun, weil es tatsächlich greifbare Vorteile hat.

+0

@Downvoters Die Variabilität in den Antworten zu sehen, ohne klare Angaben darüber zu geben, was das OP eigentlich will, außer "DRY" zu vermeiden, ist ein starker Hinweis auf "unklar, was du fragst" oder "zu breit". – user5666873

+0

Wenn Sie denken, dass eine Frage "zu weit gefasst" ist oder "unklar, was Sie fragen", empfiehlt es sich, die Frage zu verengen oder zu klären, und wenn das nicht funktioniert, schließen Sie sie ab. Es ist keine Entschuldigung, um breite oder unklare Antworten zu veröffentlichen. Das heißt, ich habe nicht das Gefühl, dass Ihre Antwort eine Abstimmung nach unten verdient. – 5gon12eder

+1

Ich habe Instanzen in verschiedenen Programmen gefunden, bei denen ich nur wählen möchte, welche Variable zugewiesen werden soll. Ich weiß, dass es verschiedene Möglichkeiten gibt, den Wert einer Variablen zu wählen, daher bin ich natürlich nur neugierig, ob das auch umgekehrt der Fall ist, da ich routinemäßig auf die Notwendigkeit gestoßen bin. Für mich sollte so etwas wie eine switch-case-Anweisung verwendet werden, wenn verschiedene Fälle signifikant unterschiedlichen Code haben, nicht für die n-malige Wiederholung einer Anweisung. Ich möchte nicht hier und jetzt ein Problem lösen, sondern lernen, welche Techniken mir zur Verfügung stehen. – thegreatjedi