• Namespaces
    Variants
    Actions

    if statement

    From cppreference.com
    < cpp‎ | language

    Conditionally executes another statement.

    Used where code needs to be executed based on a run-time or compile-time condition.

    Contents

    [edit] Syntax

    attr(optional) if ( condition ) statement-true (until C++17)
    attr(optional) if ( condition ) statement-true else statement-false (until C++17)
    attr(optional) if constexpr(optional) ( init-statement(optional) condition ) statement-true (since C++17)
    attr(optional) if constexpr(optional) ( init-statement(optional) condition ) statement-true else statement-false (since C++17)
    attr(C++11) - any number of attributes
    condition - one of
    init-statement(C++17) - either
    • an expression statement (which may be a null statement ";")
    • a simple declaration, typically a declaration of a variable with initializer, but it may declare arbitrary many variables or be a decomposition declaration
    Note that any init-statement must end with a semicolon ;, which is why it is often described informally as an expression or a declaration followed by a semicolon.
    statement-true - any statement (often a compound statement), which is executed if condition evaluates to true
    statement-false - any statement (often a compound statement), which is executed if condition evaluates to false

    [edit] Explanation

    If the condition yields true after conversion to bool, statement-true is executed.

    If the else part of the if statement is present and condition yields false after conversion to bool, statement-false is executed.

    In the second form of if statement (the one including else), if statement-true is also an if statement then that inner if statement must contain an else part as well (in other words, in nested if-statements, the else is associated with the closest if that doesn't have an else)

    #include <iostream> int main() {    // simple if-statement with an else clause    int i = 2;    if (i > 2) {        std::cout << i << " is greater than 2\n";    } else {        std::cout << i << " is not greater than 2\n";    }     // nested if-statement    int j = 1;    if (i > 1)        if (j > 2)            std::cout << i << " > 1 and " << j << " > 2\n";        else // this else is part of if (j > 2), not of if (i > 1)            std::cout << i << " > 1 and " << j << " <= 2\n";    // declarations can be used as conditions with dynamic_cast   struct Base {        virtual ~Base() {}   };   struct Derived : Base {       void df() { std::cout << "df()\n"; }   };   Base* bp1 = new Base;   Base* bp2 = new Derived;    if (Derived* p = dynamic_cast<Derived*>(bp1)) // cast fails, returns nullptr       p->df();  // not executed    if (auto p = dynamic_cast<Derived*>(bp2)) // cast succeeds       p->df();  // executed}

    Output:

    2 is not greater than 22 > 1 and 1 <= 2df()


    If Statements with Initializer

    If init-statement is used, the if statement is equivalent to

    {
    init_statement
    attr(optional) if constexpr(optional) ( condition )
    statement-true

    }

    or

    {
    init_statement
    attr(optional) if constexpr(optional) ( condition )
    statement-true
    else
    statement-false

    }

    Except that names declared by the init-statement (if init-statement is a declaration) and names declared by condition (if condition is a declaration) are in the same scope, which is also the scope of both statements.

    std::map<int, std::string> m;std::mutex mx;extern bool shared_flag; // guarded by mxint demo() {   if (auto it = m.find(10); it != m.end()) { return it->second.size(); }   if (char buf[10]; std::fgets(buf, 10, stdin)) { m[0] += buf; }   if (std::lock_guard lock(mx); shared_flag) { unsafe_ping(); shared_flag = false; }   if (int s; int count = ReadBytesWithSignal(&s)) { publish(count); raise(s); }   if (auto keywords = {"if", "for", "while"};       std::any_of(keywords.begin(), keywords.end(),                   [&s](const char* kw) { return s == kw; })) {     std::cerr << "Token must not be a keyword\n";   }}
    (since C++17)

    Constexpr If

    The statement that begins with if constexpr is known as the constexpr if statement.

    In a constexpr if statement, the value of condition must be a contextually converted constant expression of type bool. If the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded.

    The return statements in a discarded statement do not participate in function return type deduction:

    template <typename T>auto get_value(T t) {    if constexpr (std::is_pointer_v<T>)        return *t; // deduces return type to int for T = int*    else        return t;  // deduces return type to int for T = int}

    The discarded statement can odr-use a variable that is not defined

    extern int x; // no definition of x requiredint f() {if constexpr (true)    return 0;else if (x)    return x;else    return -x;}

    If a constexpr if statement appears inside a templated entity, and if condition is not value-dependent after instantiation, the discarded statement is not instantiated when the enclosing template is instantiated .

    template<typename T, typename ... Rest>void g(T&& p, Rest&& ...rs) {    // ... handle p    if constexpr (sizeof...(rs) > 0)        g(rs...); // never instantiated with an empty argument list.}

    Outside a template, a discarded statement is fully checked. if constexpr is not a substitute for the #if preprocessing directive:

    void f() {    if constexpr(false) {        int i = 0;        int *p = i; // Error even though in discarded statement    }}


    Note: an example where the condition remains value-dependent after instantiation is a nested template, e.g.

    template<class T> void g() {    auto lm = [](auto p) {        if constexpr (sizeof(T) == 1 && sizeof p == 1) {           // this condition remains value-dependent after instantiation of g<T>        }    };}

    Note: the discarded statement can't be ill-formed for every possible specialization:

    template <typename T>void f() {     if constexpr (std::is_arithmetic_v<T>)         // ...     else       static_assert(false, "Must be arithmetic"); // ill-formed: invalid for every T}

    The common workaround for such a catch-all statement is a type-dependent expression that is always false:

    template<class T> struct dependent_false : std::false_type {};template <typename T>void f() {     if constexpr (std::is_arithmetic_v<T>)         // ...     else       static_assert(dependent_false<T>::value, "Must be arithmetic"); // ok}

    Labels (goto targets, case labels, and default:) appearing in a substatement of a constexpr if can only be referenced (by switch or goto) in the same substatement.

    (since C++17)

    [edit] Notes

    If statement_true or statement_false is not a compound statement, it is treated as if it were:

    if (x)    int i;// i is no longer in scope

    is the same as

    if (x) {    int i;} // i is no longer in scope

    The scope of the name introduced by condition, if it is a declaration, is the combined scope of both statements' bodies:

    if (int x = f()) {    int x; // error: redeclaration of x} else {    int x; // error: redeclaration of x}

    If statement-true is entered by goto or longjmp, statement_false is not executed.

    (since C++14)

    Switch and goto are not allowed to jump into a branch of constexpr if statement.

    (since C++17)

    [edit] Keywords

    if,else,constexpr

    [edit] See Also

    C documentation for if statement

        1. http://www.iixn02.cn | http://m.iixn02.cn | http://wap.iixn02.cn | http://3g.iixn02.cn | http://4g.iixn02.cn | http://5g.iixn02.cn | http://mobile.iixn02.cn | http://vip.iixn02.cn | http://ios.iixn02.cn | http://anzhuo.iixn02.cn | http://bb.iixn02.cn | http://89752.iixn02.cn | http://289083.iixn02.cn | http://19.iixn02.cn | http://0f469.iixn02.cn | http://8.iixn02.cn | 撩起裙子跨腿坐上去视频