una ternario operator operador linea ejemplo corto c# c++ c ternary

c# - operator - ¿Es este un uso razonable del operador ternario?



ternary operator c (16)

¿Hay algún problema de comprensión / mantenimiento que resulte de código como

inVar1 == 0 ? NULL : v.push_back(inVar1); inVar2 == 0 ? NULL : v.push_back(inVar2);

Etcétera.

La idea posiblemente confusa es usar el operador ternario para el flujo del programa en lugar de la asignación de variables, que es la explicación habitual.

No he visto normas de codificación en el trabajo que aborden este uso, así que aunque me siento cómodo haciendo esto, me gustaría saber si existe una buena razón para no hacerlo.


Como se mencionó en los comentarios, esto no es válido en C ++ . GCC, por ejemplo, emitirá un error en este código:

error: `(&v)->std::vector<_Tp, _Alloc>::push_back [with _Tp = int, _Alloc = std::allocator<int>](((const int&)((const int*)(&inVar1))))'' has type `void'' and is not a throw-expression

Sin embargo, eso se puede solucionar con el casting:

inVar1 == 0 ? (void)0 : v.push_back(inVar1); inVar2 == 0 ? (void)0 : v.push_back(inVar2);

¿Pero a qué precio? ¿Y para qué?

No es como usar el operador ternario aquí es más conciso que un enunciado if en esta situación:

inVar1 == 0 ? NULL : v.push_back(inVar1); if(inVar1 != 0) v.push_back(inVar1);


Creo que a veces los ternarios son un mal necesario en las listas de inicializadores para los constructores. Los uso principalmente para constructores en los que quiero asignar memoria y establecer algún puntero para señalarlo antes que el cuerpo del constructor.

Un ejemplo, suponga que tiene una clase de almacenamiento de enteros que desea tener toma un vector como entrada pero la representación interna es una matriz:

class foo { public: foo(std::vector<int> input); private: int* array; unsigned int size; }; foo:foo(std::vector<int> input):size(input.size()), array( (input.size()==0)? NULL : new int[input.size]) { //code to copy elements and do other start up goes here }

Así es como uso el operador ternario. No creo que sea tan confuso como algunas personas lo hacen, pero creo que uno debe limitar la cantidad que lo usan.


Creo que esto debería evitarse. Podría usar una instrucción if de 1 línea en su lugar.

if(inVar1 != 0) v.push_back(inVar1);


Creo que sería mejor que te desempeñes en una estructura adecuada. Incluso prefiero tener llaves siempre con mis estructuras if, en caso de que tenga que agregar líneas más adelante a la ejecución condicional.

if (inVar != 0) { v.push_back(inVar); }


El operador ternario está destinado a devolver un valor.

IMO, no debe mutar el estado, y se debe usar el valor de retorno.

En el otro caso, use declaraciones if. Si las declaraciones están destinadas a ejecutar bloques de código.


El ternario es algo bueno, y generalmente promuevo su uso.

Lo que estás haciendo aquí sin embargo empaña su credibilidad. Es más corto, sí, pero es innecesariamente complicado.


Los compiladores en estos días harán un tan rápido como un operador ternario.

Tu objetivo debería ser lo fácil que sea para otro desarrollador de software leer.

Yo voto por

if ( inVar != 0 ) { v.push_back( inVar ); }

¿Por qué los corchetes ... porque un día es posible que desee poner algo más allí y los corchetes están pre-hecho para usted. La mayoría de los editores estos días los pondrán de todos modos.


Si bien, en la práctica, estoy de acuerdo con los sentimientos de aquellos que desalientan este tipo de escritura (cuando lees, tienes que hacer un trabajo extra para escanear la expresión por sus efectos secundarios), me gustaría ofrecer

!inVar1 ?: v.push_back(inVar1); !inVar2 ?: v.push_back(inVar2);

... si vas por oscuro, eso es. GCC permite x ?: y en lugar de x ? x : y x ? x : y . :-)


Si tiene varias invocaciones de método en uno o ambos argumentos tenarios, entonces es incorrecto. Todas las líneas de código independientemente de qué enunciado deben ser breves y simples, idealmente no compuestas.


Una declaración if adecuada es más legible, como otros han mencionado. Además, cuando revisa su código con un depurador, no podrá ver fácilmente qué rama de un if se toma cuando todo está en una línea o si está utilizando una expresión ternaria:

if (cond) doIt(); cond ? noop() : doIt();

Mientras que lo siguiente es mucho mejor para dar un paso adelante (ya sea que tenga llaves o no):

if (cond) { doIt(); }


Utilizo el operador ternario cuando necesito llamar a alguna función con argumentos condicionales; en este caso, es mejor que if .

Comparar:

printf("%s while executing SQL: %s", is_sql_err() ? "Error" : "Warning", sql_msg());

con

if (is_sql_err()) printf("Error while executing SQL: %s", sql_msg()); else printf("Warning while executing SQL: %s", sql_msg());

Encuentro que el primero es más atractivo. Y cumple con el principio DRY , a diferencia de este último: no necesita escribir dos líneas casi idénticas.


Como se mencionó, no es más corto o más claro que una declaración de 1 línea si. Sin embargo, ya no es más, y no es tan difícil de asimilar. Si conoces al operador ternario, es bastante obvio lo que está sucediendo.

Después de todo, no creo que alguien tenga un problema si se le está asignando a una variable (incluso si también estuviera mutando):

var2 = inVar1 == 0 ? NULL : v.push_back(inVar1);

El hecho de que el operador ternario siempre devuelva un valor - IMO - es irrelevante. Ciertamente, no es necesario que use todos los valores devueltos ... después de todo, una asignación devuelve un valor.

Dicho eso, lo reemplazaría con una declaración if si lo encontré con una rama NULL.

Pero , si reemplazó una declaración de 3 líneas if:

if (inVar == 0) { v.doThingOne(1); } else { v.doThingTwo(2); }

con:

invar1 == 0 ? v.doThingOne(1) : v.doThingTwo(2);

Podría dejarlo ... dependiendo de mi estado de ánimo. ;)


La mayoría de los ternarios torturados (¿cómo es eso de la aliteración?) Veo que son simplemente intentos de poner la lógica que realmente pertenece en una declaración if en un lugar donde una sentencia if no pertenece o no puede ir.

Por ejemplo:

if (inVar1 != 0) v.push_back(inVar1); if (inVar2 != 0) v.push_back(inVar2);

funciona suponiendo que v.push_back es nulo, pero ¿qué sucede si devuelve un valor que necesita pasar a otra función? En ese caso, debería verse algo como esto:

SomeType st; if (inVar1 != 0) st = v.push_back(inVar1); else if (inVar2 != 0) st = v.push_back(inVar2); SomeFunc(st);

Pero eso es más para digerir un código tan simple. Mi solución: definir otra función.

SomeType GetST(V v, int inVar1, int inVar2){ if (inVar1 != 0) return v.push_back(inVar1); if (inVar2 != 0) return v.push_back(inVar2); } //elsewhere SomeFunc(GetST(V v, inVar1, inVar2));

En cualquier caso, el punto es el siguiente: si tienes una lógica que está demasiado torturada para un ternario pero que desordene tu código si se coloca en una declaración if, ¡ponlo en otro lugar!


Creo que es confuso y mucho más difícil de leer que simplemente escribir;

if (inVar != 0) v.push_back(inVar);

Tuve que escanear tu ejemplo varias veces para descubrir cuál sería el resultado con certeza. Incluso preferiría una declaración if () {} de una sola línea que tu ejemplo, y odio las declaraciones if de una sola línea :)


inVar1 != 0 || v.push_back(inVar1); inVar2 != 0 || v.push_back(inVar2);

patrón común encontrado en idiomas como Perl.


Su uso del operador ternario no le gana nada y perjudica la legibilidad de los códigos.

Como el operador ternario devuelve un valor que no está utilizando, es un código impar. El uso de un if es mucho más claro en un caso como el tuyo.