Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      if statement

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      if
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
       

      Conditionally executes another statement.

      Used where code needs to be executed based on a condition, or whether theif statement is evaluated in a manifestly constant-evaluated context(since C++23).

      Contents

      [edit]Syntax

      attr (optional)ifconstexpr(optional)
      (init-statement (optional)condition)statement-true
      (1)
      attr (optional)ifconstexpr(optional)
      (init-statement (optional)condition)statement-trueelsestatement-false
      (2)
      attr (optional)if!(optional)constevalcompound-statement (3)(since C++23)
      attr (optional)if!(optional)constevalcompound-statementelsestatement (4)(since C++23)
      1)if statement without anelse branch
      2)if statement with anelse branch
      3) consteval if statement without anelse branch
      4) consteval if statement with anelse branch
      attr -(since C++11) any number ofattributes
      constexpr -(since C++17) if present, the statement becomes aconstexpr if statement
      init-statement -(since C++17) either
      (since C++23)

      Note that anyinit-statement must end with a semicolon. This is why it is often described informally as an expression or a declaration followed by a semicolon.

      condition - acondition
      statement-true - thestatement to be executed ifcondition yieldstrue
      statement-false - the statement to be executed ifcondition yieldsfalse
      compound-statement - thecompound statement to be executed if theif statement is evaluated in amanifestly constant-evaluated context (or is not evaluated in such a context if! is precedingconsteval)
      statement - the statement (must be a compound statement, seebelow) to be executed if theif statement is not evaluated in a manifestly constant-evaluated context (or is evaluated in such a context if! is precedingconsteval)

      [edit]Condition

      Acondition can either be anexpression or asimple declaration.

      • If it can be syntactically resolved as astructured binding declaration, it is interpreted as a structured binding declaration.
      (since C++26)
      • If it can be syntactically resolved as an expression, it is treated as an expression. Otherwise, it is treated as a declaration that is not a structured binding declaration(since C++26).

      When control reaches condition, the condition will yield a value, which is used to determine which branch the control will go to.

      [edit]Expression

      Ifcondition is an expression, the value it yields is the the value of the expression contextually converted tobool. If that conversion is ill-formed, the program is ill-formed.

      [edit]Declaration

      Ifcondition is a simple declaration, the value it yields is the value of the decision variable (see below) contextually converted tobool. If that conversion is ill-formed, the program is ill-formed.

      [edit]Non-structured binding declaration

      The declaration has the following restrictions:

      • Syntactically conforms to the following form:
      • type-specifier-seqdeclarator=assignment-expression
      (until C++11)
      • attribute-specifier-seq(optional)decl-specifier-seqdeclaratorbrace-or-equal-initializer
      (since C++11)

      The decision variable of the declaration is the declared variable.

      Structured binding declaration

      The declaration has the following restrictions:

      The decision variable of the declaration is the invented variableeintroduced by the declaration.

      (since C++26)

      [edit]Branch selection

      If thecondition yieldstrue,statement-true is executed.

      If theelse part of theif statement is present andcondition yieldsfalse,statement-false is executed.

      If theelse part of theif statement is present andstatement-true is also anif statement, then that innerif statement must contain anelse part as well (in other words, in nestedif statements, theelse is associated with the closestif that does not yet have an associatedelse).

      Run this code
      #include <iostream> int main(){// simple if-statement with an else clauseint i=2;if(i>2)std::cout<< i<<" is greater than 2\n";elsestd::cout<< i<<" is not greater than 2\n"; // nested if-statementint 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_caststruct 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

      Ifinit-statement is used, theif statement is equivalent to

      {
      init-statement
      attr (optional)ifconstexpr(optional)(condition)
      statement-true

      }

      or

      {
      init-statement
      attr (optional)ifconstexpr(optional)(condition)
      statement-true
      else
      statement-false

      }

      Except that names declared by theinit-statement (ifinit-statement is a declaration) and names declared bycondition (ifcondition is a declaration) are in the same scope, which is also the scope of bothstatement s.

      std::map<int,std::string> m;std::mutex mx;externbool shared_flag;// guarded by mx int 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(constauto keywords={"if","for","while"};        std::ranges::any_of(keywords,[&tok](constchar* kw){return tok== kw;})){std::cerr<<"Token must not be a keyword\n";}}
      (since C++17)


      Constexpr if

      The statement that begins withifconstexpr is known as theconstexpr if statement. All substatements of a constexpr if statement arecontrol-flow-limited statements.

      In a constexpr if statement,condition must beacontextually converted constant expression of typebool(until C++23)an expressioncontextually converted tobool, where the conversion is aconstant expression(since C++23).

      Ifcondition yieldstrue, thenstatement-false is discarded (if present), otherwise,statement-true is discarded.

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

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

      The discarded statement canODR-use a variable that is not defined:

      externint x;// no definition of x required int f(){ifconstexpr(true)return0;elseif(x)return x;elsereturn-x;}

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

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

      If a constexpr if statement appears inside atemplated entity, and ifcondition is notvalue-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 pifconstexpr(sizeof...(rs)>0)        g(rs...);// never instantiated with an empty argument list}

      The condition remains value-dependent after instantiation is a nested template:

      template<class T>void g(){auto lm=[=](auto p){ifconstexpr(sizeof(T)==1&& sizeof p==1){// this condition remains value-dependent after instantiation of g<T>,// which affects implicit lambda captures// this compound statement may be discarded only after// instantiation of the lambda body}};}

      The discarded statement cannot be ill-formed for every possible specialization:

      template<typename T>void f(){ifconstexpr(std::is_arithmetic_v<T>)// ...else{using invalid_array=int[-1];// ill-formed: invalid for every T        static_assert(false,"Must be arithmetic");// ill-formed before CWG2518}}

      The common workaround before the implementation ofCWG issue 2518 for such a catch-all statement is a type-dependent expression that is alwaysfalse:

      template<typename>constexprbool dependent_false_v=false; template<typename T>void f(){ifconstexpr(std::is_arithmetic_v<T>)// ...else{// workaround before CWG2518        static_assert(dependent_false_v<T>,"Must be arithmetic");}}

      Atypedef declarationoralias declaration(since C++23) can be used as theinit-statement of a constexpr if statement to reduce the scope of the type alias.

      This section is incomplete
      Reason: no example
      (since C++17)


      Consteval if

      The statement that begins withif consteval is known as theconsteval if statement. All substatements of a consteval if statement arecontrol-flow-limited statements.

      statement must be a compound statement, and it will still be treated as a part of the consteval if statement even if it is not a compound statement (and thus results in a compilation error):

      Run this code
      constexprvoid f(bool b){if(true)if consteval{}else;// error: not a compound-statement// else not associated with outer if}

      If a consteval if statement is evaluated in amanifestly constant-evaluated context,compound-statement is executed. Otherwise,statement is executed if it is present.

      If the statement begins withif!consteval, thecompound-statement andstatement (if any) must both be compound statements. Such statements are not considered consteval if statements, but are equivalent to consteval if statements:

      • if!consteval{/* stmt */} is equivalent to
      if consteval{}else{/* stmt */}.
      • if!consteval{/* stmt-1 */}else{/* stmt-2 */} is equivalent to
      if consteval{/* stmt-2 */}else{/* stmt-1 */}.

      compound-statement in a consteval if statement (orstatement in the negative form) is in animmediate function context, in which a call to an immediate function needs not to be a constant expression.

      Run this code
      #include <cmath>#include <cstdint>#include <cstring>#include <iostream> constexprbool is_constant_evaluated()noexcept{if consteval{returntrue;}else{returnfalse;}} constexprbool is_runtime_evaluated()noexcept{if not consteval{returntrue;}else{returnfalse;}} constevalstd::uint64_t ipow_ct(std::uint64_t base,std::uint8_t exp){if(!base)return base;std::uint64_t res{1};while(exp){if(exp&1) res*= base;        exp/=2;        base*= base;}return res;} constexprstd::uint64_t ipow(std::uint64_t base,std::uint8_t exp){if consteval// use a compile-time friendly algorithm{return ipow_ct(base, exp);}else// use runtime evaluation{returnstd::pow(base, exp);}} int main(int,constchar* argv[]){    static_assert(ipow(0,10)==0&& ipow(2,10)==1024);std::cout<< ipow(std::strlen(argv[0]),3)<<'\n';}
      (since C++23)

      [edit]Notes

      Ifstatement-true orstatement-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 bycondition, 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}

      Ifstatement-true is entered bygoto orlongjmp,condition is not evaluated andstatement-false is not executed.

      Built-in conversions are not allowed in thecondition of a constexpr if statement, except for non-narrowingintegral conversions tobool.

      (since C++17)
      (until C++23)
      Feature-test macroValueStdFeature
      __cpp_if_constexpr201606L(C++17)constexprif
      __cpp_if_consteval202106L(C++23)constevalif

      [edit]Keywords

      if,else,constexpr,consteval

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 631C++98the control flow was unspecified if the
      first substatement is reached via a label
      the condition is not evaluated and the second
      substatement is not executed (same as in C)

      [edit]See also

      detects whether the call occurs within a constant-evaluated context
      (function)[edit]
      C documentation forif statement
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/if&oldid=177112"

      [8]ページ先頭

      ©2009-2025 Movatter.jp