En el ejemplo de Stroustrup, ¿qué significa el colon en "retorno 1: 2"?

163

No entiendo un uso particular de un colon.

Lo encontré en el libro El lenguaje de programación C ++ de Bjarne Stroustrup, cuarta edición, sección 11.4.4 "Llamada y devolución", página 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
}

Los dos puntos confusos aparecen en la línea 7, en la declaración return 1 : 2. No tengo idea de lo que podría ser. No es una etiqueta ni un operador ternario.

Parece un operador ternario condicional sin el primer miembro (y sin el ?), pero en ese caso no entiendo cómo podría funcionar sin una condición.

Piockñec
fuente
66
Es un error de compilación de mi parte (gcc y clang). Además, todas esas líneas necesitan punto y coma, pero siguen siendo un error.
Cruz Jean
216
Nota para el moderador: piense detenidamente antes de emitir un voto para cerrar esta pregunta como "error tipográfico". Sí, el problema es un error tipográfico, pero no es un error que hizo el autor de la pregunta. Más bien, se encuentra en un libro publicado. Eso significa que esta pregunta y sus respuestas pueden ser útiles para otros en el futuro, lo cual es un fuerte contraindicador para cerrarlo como un error tipográfico. (ACTUALIZACIÓN: Este tema ahora se está discutiendo en Meta ; por favor, siéntase libre de pesar allí).
Cody Gray
3
Quizás la mejor respuesta sería: Intente compilar el código; Si no se compila, es una buena indicación de que es un error tipográfico.
jrw32982 apoya a Monica
Puedo pensar en una serie de ejemplos fuera de mi cabeza que no se compilan (o incluso causan un error interno del compilador) en un compilador, pero son aceptados sin problemas en uno diferente
J. Antonio Pérez,
1
@John Intenté algunas expresiones de pliegue con MSVC y no se compilaron. ¿Entonces claramente todo el capítulo que acabo de leer debe ser un error tipográfico? ;) Los compiladores de C ++ no pueden compilar código de C ++ válido todo el tiempo, proviene del lenguaje que es absurdamente complicado.
Voo

Respuestas:

205

Es un error tipográfico en el libro. Mire Errata para las impresiones segunda y tercera del lenguaje de programación C ++ . El ejemplo debe ser el siguiente:

auto z3 =[y]() { return (y) ? 1 : 2; }
SM
fuente
11
¿Por qué (y)y no solo y?
Little Helper
77
@LittleHelper Quizás sea una mejor práctica o algo así, siempre lo veo escrito así. Tal vez para evitar confusiones con comparaciones más complicadas ...
Redwolf Programs
28
Personalmente, a menudo lo uso (cond) ? a : bpara mayor claridad: me ayuda a evitar la lectura errónea, por ejemplo, la declaración foo = x > y ? a : bcomo foo = x ...al leer el código.
user1686
8
@LittleHelper No es realmente necesario allí. Sin embargo, en una macro similar a una función, se recomienda poner paréntesis alrededor de los argumentos donde se usan, porque de lo contrario la expansión de los argumentos puede dar un comportamiento inesperado. Considere una macro similar a una función para duplicar un valor "foo (x) x * 2" donde lo llame con "foo (2 + 3)". El resultado será 2+ (3 * 2) porque el argumento se expande tal cual y las reglas de precedencia se hacen cargo. Si su macro es "foo (x) (x) * 2", obtendrá correctamente (2 + 3) * 2. Puede ser que Stroustrup tenga la costumbre de usar ese estilo en todas partes para codificar la seguridad.
Graham
2
@Graham Muy poco probable. Stroustrup esencialmente no escribe macros de funciones (las funciones en línea de C ++ son mejores). Es mucho más probable que el operador ternario tenga reglas de precedencia algo complicadas, por lo que es bueno aclarar habitualmente la precedencia con parens.
Martin Bonner apoya a Mónica
19

Me parece un simple error tipográfico. Probablemente debería ser:

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

Tenga en cuenta que, dado que la lambda no toma ningún parámetro, los parens son opcionales. Puede usar esto en su lugar, si lo prefiere:

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

return 1 : 2; es un error de sintaxis, no es un código válido.

Una declaración correcta sería más como en su return (y) ? 1 : 2;lugar.

Remy Lebeau
fuente