switch
statementGeneral topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
| ||||||||||||||||
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 | ||||||||||||||||
| ||||||||||||||||
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 | ||||||||||||||||
Transfers control to one of several statements, depending on the value of a condition.
Contents |
attr (optional)switch ( init-statement (optional)condition) statement | |||||||||
attr | - | (since C++11) any number ofattributes | ||
init-statement | - | (since C++17) any of the following:
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 | - | a statement (typically a compound statement) |
Acondition can either be anexpression or asimple declaration.
| (since C++26) |
When control reaches condition, the condition will yield a value, which is used to determine which label the control will go to.
Ifcondition is an expression, the value it yields is the the value of the expression.
Ifcondition is a simple declaration, the value it yields is the value of the decision variable (see below).
The declaration has the following restrictions:
| (until C++11) |
| (since C++11) |
The decision variable of the declaration is the declared variable.
Structured binding declarationThe declaration has the following restrictions:
The decision variable of the declaration is the invented variableeintroduced by the declaration. | (since C++26) |
condition can only yield the following types:
If the yielded value is of a class type, it is contextually implicitly converted to an integral or enumeration type.
If the (possibly converted) type is subject tointegral promotions , the yielded value is converted to the promoted type.
Any statement within theswitch statement can be labeled with one or more following labels:
attr (optional)case constant-expression: | (1) | ||||||||
attr (optional)default: | (2) | ||||||||
attr | - | (since C++11) any number ofattributes |
constant-expression | - | aconverted constant expression of the adjusted type of theswitch condition |
Acase ordefault label is associated with the innermostswitch statement enclosing it.
If any of the following conditions is satisfied, the program is ill-formed:
When the condition of aswitch statement yields a (possibly converted) value:
case anddefault labels in themselves do not alter the flow of control. To exit from aswitch statement from the middle, seebreak statements.
Compilers may issue warnings on fallthrough (reaching the nextcase ordefault label without abreak) unless the attribute[[fallthrough]]
appears immediately before thecase label to indicate that the fallthrough is intentional(since C++17).
switch statements with initializerIfinit-statement is used, the switch statement is equivalent to
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 ofstatement. | (since C++17) |
Because transfer of control isnot permitted to enter the scope of a variable, if a declaration statement is encountered inside thestatement, it has to be scoped in its own compound statement:
The following code shows several usage cases of theswitch statement:
#include <iostream> int main(){constint i=2;switch(i){case1:std::cout<<'1';case2:// execution starts at this case labelstd::cout<<'2';case3:std::cout<<'3';[[fallthrough]];// C++17 attribute to silent the warning on fallthroughcase5:std::cout<<"45";break;// execution of subsequent statements is terminatedcase6:std::cout<<'6';} std::cout<<'\n'; switch(i){case4:std::cout<<'a';default:std::cout<<'d';// there are no applicable constant expressions// therefore default is executed} std::cout<<'\n'; switch(i){case4:std::cout<<'a';// nothing is executed} // when enumerations are used in a switch statement, many compilers// issue warnings if one of the enumerators is not handledenum color{ RED, GREEN, BLUE};switch(RED){case RED:std::cout<<"red\n";break;case GREEN:std::cout<<"green\n";break;case BLUE:std::cout<<"blue\n";break;} // the C++17 init-statement syntax can be helpful when there is// no implicit conversion to integral or enumeration typestruct Device{enum State{ SLEEP, READY, BAD};auto state()const{return m_state;} /* ... */ private: State m_state{};}; switch(auto dev= Device{}; dev.state()){case Device::SLEEP:/* ... */break;case Device::READY:/* ... */break;case Device::BAD:/* ... */break;} // pathological examples // the statement does not have to be a compound statementswitch(0)std::cout<<"this does nothing\n"; // labels do not require a compound statement eitherswitch(int n=1)case0:case1:std::cout<< n<<'\n';}
Output:
2345dred1
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 1767 | C++98 | condition s of types that are not subject to integral promotion could not be promoted | do not promote condition s of these types |
CWG 2629 | C++98 | condition could be a declaration of a floating-point variable | prohibited |
C documentation forswitch |
1. | Loop unrolling using Duff's Device |
2. | Duff's device can be used to implement coroutines in C/C++ |