Dans l'exemple de Stroustrup, que signifie le signe deux-points dans «return 1: 2»?

163

Je ne comprends pas une utilisation particulière des deux points.

Je l'ai trouvé dans le livre The C ++ Programming Language de Bjarne Stroustrup, 4e édition, section 11.4.4 "Call and Return", page 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
}

Les deux points déroutants apparaissent à la ligne 7, dans la déclaration return 1 : 2. Je n'ai aucune idée de ce que cela pourrait être. Ce n'est pas une étiquette ou un opérateur ternaire.

Cela ressemble à un opérateur ternaire conditionnel sans le premier membre (et sans le ?), mais dans ce cas, je ne comprends pas comment cela pourrait fonctionner sans condition.

Piockñec
la source
6
C'est une erreur de compilation de ma part (gcc et clang). De plus, toutes ces lignes ont besoin de points-virgules, mais toujours une erreur.
Cruz Jean
216
Note du modérateur: Veuillez bien réfléchir avant de voter pour fermer cette question comme une "faute de frappe". Oui, le problème est une faute de frappe, mais ce n'est pas une faute de frappe du demandeur. C'est plutôt celui que l'on trouve dans un livre publié. Cela signifie que cette question et ses réponses pourraient bien être utiles à d'autres à l'avenir, ce qui est un contre-indicateur puissant pour la classer comme une faute de frappe. (MISE À JOUR: Ce sujet est en cours de discussion sur Meta ; n'hésitez pas à y peser.)
Cody Gray
3
La meilleure réponse serait peut-être: essayez de compiler le code; s'il ne compile pas, c'est une bonne indication qu'il s'agit d'une faute de frappe.
jrw32982 soutient Monica
Je peux penser à un certain nombre d'exemples qui ne parviennent pas à compiler (ou même provoquent une erreur interne du compilateur) sur un compilateur, mais qui sont acceptés sans problème sur un autre
J.Antonio Perez
1
@John J'ai juste essayé quelques expressions de pli avec MSVC et elles n'ont pas compilé. Il est donc clair que tout le chapitre que je viens de lire doit être une faute de frappe? ;) Les compilateurs C ++ ne parviennent pas à compiler du code C ++ valide tout le temps, cela vient du fait que le langage est absurdement compliqué.
Voo

Réponses:

205

C'est une faute de frappe dans le livre. Regardez Errata pour les 2e et 3e impressions du langage de programmation C ++ . L'exemple doit être comme ci-dessous:

auto z3 =[y]() { return (y) ? 1 : 2; }
SM
la source
11
Pourquoi (y)et pas juste y?
Little Helper
7
@LittleHelper C'est peut-être une bonne pratique ou quelque chose comme ça, je le vois toujours écrit comme ça. Peut-être pour éviter toute confusion avec des comparaisons plus compliquées ...
Programmes Redwolf
28
Personnellement, j'utilise souvent (cond) ? a : bpour plus de clarté - cela m'aide à éviter de mal interpréter, par exemple, la déclaration foo = x > y ? a : bcomme foo = x ...lors du survol du code.
user1686
8
@LittleHelper Ce n'est pas vraiment nécessaire là-bas. Cependant, dans une macro de type fonction, il est préférable de placer des parenthèses autour des arguments là où ils sont utilisés, car sinon, l'expansion des arguments peut donner un comportement inattendu. Considérez une macro de type fonction pour doubler une valeur "foo (x) x * 2" où vous l'appelez avec "foo (2 + 3)". Le résultat sera 2+ (3 * 2) car l'argument est développé tel quel et les règles de priorité prennent le dessus. Si votre macro est "foo (x) (x) * 2" alors vous obtiendrez correctement (2 + 3) * 2. Il se peut que Stroustrup ait l'habitude d'utiliser ce style partout pour la sécurité du codage.
Graham
2
@Graham Très improbable. Stroustrup n'écrit essentiellement pas de macros de fonctions (les fonctions en ligne C ++ sont meilleures). Il est beaucoup plus probable que l'opérateur ternaire ait des règles de précédence quelque peu compliquées, il est donc bon de clarifier habituellement la priorité avec des parenthèses.
Martin Bonner soutient Monica
19

Cela me ressemble à une simple faute de frappe. Devrait probablement être:

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

Notez que puisque le lambda ne prend aucun paramètre, les parens sont facultatives. Vous pouvez utiliser ceci à la place, si vous préférez:

auto z3 =[y] { return y ? 1 : 2; }
Jerry Coffin
la source
11

return 1 : 2; est une erreur de syntaxe, ce n'est pas du code valide.

Une déclaration correcte serait plutôt la même return (y) ? 1 : 2;chose.

Remy Lebeau
la source