while switch sirve sentencia resueltos que programacion para lenguaje else ejercicios ejemplos condiciones c++ if-statement

c++ - switch - ¿Puedo escribir esta declaración if con una declaración de variable en una línea?



switch c++ (5)

Antes de C ++ 17 puedes definir una clase contenedora, como aquí:

#include <utility> template<typename T> class NotT { T t; public: template<typename U> NotT(U&& u) : t(std::move(u)) {} explicit operator bool() const { return !t; } T & value() { return t; } T const& value() const { return t; } }; template<typename T> NotT<T> Not(T&& t) { return NotT<T>(std::move(t)); } #include <memory> #include <iostream> int main() { if(auto p=Not(std::make_shared<int>(2134))) std::cout << "!p: p=" << p.value().get() << ''/n''; else std::cout << "!!p: p=" << p.value().get() << ", *p=" << *p.value() << ''/n''; }

Ejemplo en vivo

Me preguntaba si había una manera de poner esto en una línea.

if (auto r = getGlobalObjectByName(word)) r->doSomething; // This works fine if (!auto r = getGlobalObjectByName(word)) r->doSomething; // Says "expected an expression" if (auto r = getGlobalObjectByName(word) == false) r->doSomething; // Also doesn''t work.

También traté de rodearlo con corchetes adicionales, pero parece que no funciona. Encuentro esto realmente conveniente hacerlo en una línea.


Desde C ++ 17 puedes usar un inicializador if-statement :

if (auto r = getGlobalObjectByName(word); !r) r->doSomething;

La semántica es:

if (init-statement; condition) statement

La única diferencia con respecto a la instrucción if "tradicional" es la instrucción init-statement , que inicializa una variable en el ámbito del bloque, similar a for-loops.


Lo que estás tratando de hacer está bien. Al definir la variable dentro de si restringe su alcance . Eso ayuda a reducir el número de variables perdidas después de que hayan cumplido su propósito.

Usando esta técnica, si quieres seguir el camino negativo , necesitas usar algo como esto:

if(auto r = getGlobalObjectByName(word)) { r->doSomething(); } else { // r == nullptr // so do something else }


Si tiene C ++ 17, use el formulario if (init statement; condition) . Si no, tienes tres opciones:

  • Deja de tratar de mantener todo esto en una línea. Por ejemplo:

    auto r = getGlobalObjectByName(word); if (!r) r->doSomething();

  • Use un else :

    if (auto r = getGlobalObjectByName(word)) {} else r->doSomething();

(Tenga en cuenta que esto requiere que r sea ​​un puntero inteligente con una semántica muy extraña para la función operator bool() del operator bool() . OTOH, supongo que esto es una pequeña pieza de código de ejemplo, en lugar de su código real).

Creo que solo usaría el formulario else si fuera realmente importante mantener todo en una línea (para preservar un formato tabular del código, por ejemplo).


También hay una manera de hacer esto con lambdas y C ++ 14 pero parece bastante tonto.

[](auto r){ if(!r)r->doSomething(); }(getGlobalObjectByName(word));

En C ++ 11 también podrías hacer este lío horrible (la misma idea, simplemente no hay auto )

[](decltype(getGlobalObjectByName(word)) r){ if(!r)r->doSomething(); }(getGlobalObjectByName(word));

Ciertamente, no es mejor que esta versión más clara de C ++ 11 mencionada por Martin Bonner :

{ auto r = getGlobalObjectByName(word); if(!r)r->doSomething(); }

Aquí su código es claro que usted quiere que r esté solo por la duración de la instrucción if.