1. 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.czmu78.cn | http://m.czmu78.cn | http://wap.czmu78.cn | http://3g.czmu78.cn | http://4g.czmu78.cn | http://5g.czmu78.cn | http://mobile.czmu78.cn | http://vip.czmu78.cn | http://ios.czmu78.cn | http://anzhuo.czmu78.cn | http://d6f84.czmu78.cn | http://0.czmu78.cn | http://1a9282.czmu78.cn | http://www.czmu78.cn/d1c0.html | http://www.czmu78.cn/507.html | http://www.czmu78.cn/96.html | 练功时被师兄被迫双修