Was bedeutet in Stroustrups Beispiel der Doppelpunkt in „Rückkehr 1: 2“?

163

Ich verstehe eine bestimmte Verwendung eines Doppelpunkts nicht.

Ich fand es in dem Buch The C ++ Programming Language von Bjarne Stroustrup, 4. Auflage, Abschnitt 11.4.4 "Call and Return", Seite 297:

void g(double y)
{
  [&]{ f(y); }                                               // return type is void
  auto z1 = [=](int x){ return x+y; }                        // return type is double
  auto z2 = [=,y]{ if (y) return 1; else return 2; }         // error: body too complicated
                                                             // for return type deduction
  auto z3 =[y]() { return 1 : 2; }                           // return type is int
  auto z4 = [=,y]()−>int { if (y) return 1; else return 2; } // OK: explicit return type
}

Der verwirrende Doppelpunkt erscheint in Zeile 7 der Anweisung return 1 : 2. Ich habe keine Ahnung, was es sein könnte. Es ist kein Label oder ternärer Operator.

Es scheint wie ein bedingter ternärer Operator ohne das erste Mitglied (und ohne das ?), aber in diesem Fall verstehe ich nicht, wie es ohne eine Bedingung funktionieren könnte.

Piockñec
quelle
6
Es ist ein Kompilierungsfehler auf meiner Seite (gcc und clang). Außerdem benötigen alle diese Zeilen Semikolons, aber immer noch einen Fehler.
Cruz Jean
216
Anmerkung des Moderators: Bitte überlegen Sie sehr genau, bevor Sie eine Stimme abgeben, um diese Frage als "Tippfehler" zu schließen. Ja, das Problem ist ein Tippfehler, aber es ist kein Tippfehler, den der Fragesteller gemacht hat. Es ist eher eines, das in einem veröffentlichten Buch gefunden wurde. Das bedeutet, dass diese Frage und ihre Antworten in Zukunft für andere nützlich sein können, was ein starker Gegenindikator dafür ist, sie als Tippfehler zu schließen. (UPDATE: Dieses Thema wird jetzt auf Meta diskutiert ; bitte zögern Sie nicht, dort abzuwägen.)
Cody Gray
3
Vielleicht wäre die beste Antwort: Versuchen Sie, den Code zu kompilieren; Wenn es nicht kompiliert wird, ist dies ein guter Hinweis darauf, dass es sich um einen Tippfehler handelt.
jrw32982 unterstützt Monica
Ich kann mir eine Reihe von Beispielen vorstellen, die auf einem Compiler nicht kompiliert werden können (oder sogar einen internen Compilerfehler verursachen), auf einem anderen jedoch ohne Probleme akzeptiert werden
J. Antonio Perez
1
@ John Ich habe gerade einige Fold-Ausdrücke mit MSVC ausprobiert und sie wurden nicht kompiliert. Also muss das ganze Kapitel, das ich gerade gelesen habe, ein Tippfehler sein? ;) C ++ - Compiler kompilieren nicht immer gültigen C ++ - Code, da die Sprache absurd kompliziert ist.
Voo

Antworten:

205

Es ist ein Tippfehler im Buch. Schauen Sie sich Errata für den 2. und 3. Druck der C ++ - Programmiersprache an . Das Beispiel muss wie folgt aussehen:

auto z3 =[y]() { return (y) ? 1 : 2; }
SM
quelle
11
Warum (y)und nicht nur y?
Kleiner Helfer
7
@LittleHelper Vielleicht ist es eine Best Practice oder so, ich sehe es immer so geschrieben. Vielleicht, um Verwechslungen mit komplizierteren Vergleichen zu vermeiden ...
Redwolf-Programme
28
Persönlich verwende ich es oft (cond) ? a : baus Gründen der Klarheit - es hilft mir, Fehlinterpretationen zu vermeiden, z. foo = x > y ? a : bB. foo = x ...beim Durchblättern von Code.
user1686
8
@LittleHelper Es wird dort nicht wirklich benötigt. In einem funktionsähnlichen Makro wird jedoch empfohlen, die Argumente dort, wo sie verwendet werden, in Klammern zu setzen, da andernfalls eine Erweiterung der Argumente zu unerwartetem Verhalten führen kann. Stellen Sie sich ein funktionsähnliches Makro vor, um einen Wert "foo (x) x * 2" zu verdoppeln, wobei Sie ihn mit "foo (2 + 3)" aufrufen. Das Ergebnis ist 2+ (3 * 2), da das Argument unverändert erweitert wird und Vorrangregeln übernommen werden. Wenn Ihr Makro "foo (x) (x) * 2" ist, erhalten Sie korrekt (2 + 3) * 2. Es kann sein, dass Stroustrup die Gewohnheit hat, diesen Stil überall für die Codierungssicherheit zu verwenden.
Graham
2
@ Abraham Sehr unwahrscheinlich. Stroustrup schreibt im Wesentlichen keine Funktionsmakros (C ++ - Inline-Funktionen sind besser). Viel wahrscheinlicher ist, dass der ternäre Operator etwas komplizierte Vorrangregeln hat, daher ist es gut, die Vorrangstellung mit Parens gewohnheitsmäßig zu klären.
Martin Bonner unterstützt Monica
19

Sieht für mich aus wie ein einfacher Tippfehler. Sollte wohl sein:

auto z3 =[y]() { return y ? 1 : 2; }

Beachten Sie, dass die Parens optional sind, da das Lambda keine Parameter akzeptiert. Sie können dies stattdessen verwenden, wenn Sie es vorziehen:

auto z3 =[y] { return y ? 1 : 2; }
Jerry Sarg
quelle
11

return 1 : 2; ist ein Syntaxfehler, es ist kein gültiger Code.

Eine korrekte Aussage wäre eher so return (y) ? 1 : 2;.

Remy Lebeau
quelle