if-else (instrucción) (C++)

Una instrucción if-else controla la bifurcación condicional. Las instrucciones de se if-branch ejecutan solo si se condition evalúa como un valor distinto de cero (o true). Si el valor de condition es distinto de cero, se ejecuta la siguiente instrucción y se omite la instrucción que sigue a la instrucción else opcional. De lo contrario, se omite la siguiente instrucción y, si hay una instrucción else, la instrucción siguiente else se ejecuta.

condition Las expresiones que se evalúan como distinto de cero son:

  • true
  • un puntero distinto de null,
  • cualquier valor aritmético distinto de cero, o
  • un tipo de clase que defina una conversión no ambigua a un tipo aritmético o puntero. (Para más información sobre las conversiones, consulte Conversiones estándar.)

Sintaxis

init-statement:
expression-statement
simple-declaration

condition:
expression
attribute-specifier-seqoptdecl-specifier-seqdeclaratorbrace-or-equal-initializer

statement:
expression-statement
compound-statement

expression-statement:
expressionopt;

compound-statement:
{statement-seqopt}

statement-seq:
statement
statement-seq statement

if-branch:
statement

else-branch:
statement

selection-statement:
ifconstexpropt17(init-statementopt17condition)if-branch
ifconstexpropt17(init-statementopt17condition)if-branchelseelse-branch

17 Este elemento opcional está disponible a partir de C++17.

if...else (instrucciones)

En ambos formatos de la instrucción if, se evalúa condition, que puede tener cualquier valor excepto una estructura, incluidos todos los efectos secundarios. El control pasa de la instrucción if a la siguiente instrucción del programa a menos que el if-branch o else-branch ejecutados contengan un break, continue o goto.

La cláusula else de una instrucción if...else está asociada a la instrucción if anterior más cercana del mismo ámbito que no tenga una instrucción else correspondiente.

Ejemplo

Este código de ejemplo muestra varias instrucciones if en uso, tanto con como sin else:

// if_else_statement.cpp
#include <iostream>

using namespace std;

int main()
{
    int x = 10;

    if (x < 11)
    {
        cout << "x < 11 is true!\n";  // executed
    }
    else
    {
        cout << "x < 11 is false!\n"; // not executed
    }

    // no else statement
    bool flag = false;
    if (flag == true)
    {
        x = 100; // not executed
    }

    int *p = new int(25);
    if (p)
    {
        cout << *p << "\n"; // outputs 25
    }
    else
    {
        cout << "p is null!\n"; // executed if memory allocation fails
    }
}

Salida:

x < 11 is true!
25

Instrucción if con un inicializador

A partir de C++17, una if instrucción también puede contener una init-statement expresión que declara e inicializa una variable con nombre. Use esta forma de la instrucción if cuando la variable solo sea necesaria dentro del ámbito de la instrucción if. Específico de Microsoft: este formulario está disponible a partir de la versión 15.3 de Visual Studio 2017 y requiere al menos la opción del compilador /std:c++17.

Ejemplo

// Compile with /std:c++17

#include <iostream>
#include <mutex>
#include <map>
#include <string>
#include <algorithm>

using namespace std;

map<int, string> m{ {1, "one"}, {2, "two"}, {10,"ten"} };
mutex mx;
bool shared_flag = true; // guarded by mx
int getValue() { return 42; }

int main()
{
    if (auto it = m.find(10); it != m.end())
    {
        cout << it->second << "\n";
    }

    if (int x = getValue(); x == 42)
    {
        cout << "x is 42\n";
    }

    if (lock_guard<mutex> lock(mx); shared_flag)
    {
        cout << "setting shared_flag to false\n";
        shared_flag = false;
    }

    string s{ "if" };
    if (auto keywords = { "if", "for", "while" }; any_of(keywords.begin(), keywords.end(), [&s](const char* kw) { return s == kw; }))
    {
        cout << "Error! Token must not be a keyword\n";
    }
}

Salida:

ten
x is 42
setting shared_flag to false
Error! Token must not be a keyword

Instrucciones if constexpr

A partir de C++17, puede usar una instrucción if constexpr en plantillas de función para tomar decisiones de bifurcación en tiempo de compilación sin tener que recurrir a varias sobrecargas de función. Específico de Microsoft: este formulario está disponible a partir de la versión 15.3 de Visual Studio 2017 y requiere al menos la opción del compilador /std:c++17.

Ejemplo

En este ejemplo se muestra cómo puede compilar condicionalmente una plantilla en función del tipo enviado a ella:

// Compile with /std:c++17
#include <iostream>

template<typename T>
auto Show(T t)
{
    //if (std::is_pointer_v<T>) // Show(a) results in compiler error for return *t. Show(b) results in compiler error for return t.
    if constexpr (std::is_pointer_v<T>) // This statement goes away for Show(a)
    {
        return *t;
    }
    else
    {
        return t;
    }
}

int main()
{
    int a = 42;
    int* pB = &a;

    std::cout << Show(a) << "\n"; // prints "42"
    std::cout << Show(pB) << "\n"; // prints "42"
}

La if constexpr instrucción se evalúa en tiempo de compilación y el compilador solo genera código para la if rama que coincide con el tipo del argumento enviado a la plantilla de función. Si comenta la instrucción y quita la if constexpr marca de comentario de la if instrucción, el compilador genera código para ambas ramas. Esto significa que recibe un error:

  • Si llama ShowValue(a); a se produce un error porque return *tt no es un puntero, aunque la if instrucción sea false y el código nunca se ejecute.
  • Si llama ShowValue(pB); a se produce un error porque return tt es un puntero, aunque la if instrucción sea cierta y el código nunca se ejecute.

El uso if constexpr de resuelve este problema porque solo se compila la instrucción que coincide con el tipo del argumento enviado a la plantilla de función.

Salida:

42
42

Consulte también

Instrucciones de selección
Palabras clave
Instrucción switch (C++)