8 Statements [stmt.stmt]

8.5 Selection statements [stmt.select]

Selection statements choose one of several flows of control.
selection-statement:
	if constexpr ( init-statement condition ) statement
	if constexpr ( init-statement condition ) statement else statement
	switch ( init-statement condition ) statement
See [dcl.meaning] for the optional attribute-specifier-seq in a condition.
Note
:
An init-statement ends with a semicolon.
— end note
 ]
The substatement in a selection-statement (each substatement, in the else form of the if statement) implicitly defines a block scope ([basic.scope]).
If the substatement in a selection-statement is a single statement and not a compound-statement, it is as if it was rewritten to be a compound-statement containing the original substatement.
Example
:
if (x)
  int i;
can be equivalently rewritten as
if (x) {
  int i;
}
Thus after the if statement, i is no longer in scope.
— end example
 ]

8.5.1 The if statement [stmt.if]

If the condition ([stmt.select]) yields true the first substatement is executed.
If the else part of the selection statement is present and the condition yields false, the second substatement is executed.
If the first substatement is reached via a label, the condition is not evaluated and the second substatement is not executed.
In the second form of if statement (the one including else), if the first substatement is also an if statement then that inner if statement shall contain an else part.83
If the if statement is of the form if constexpr, the value of the condition shall be a contextually converted constant expression of type bool; this form is called a constexpr if statement.
If the value of the converted condition is false, the first substatement is a discarded statement, otherwise the second substatement, if present, is a discarded statement.
During the instantiation of an enclosing templated entity ([temp.pre]), if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.
Note
:
Odr-uses in a discarded statement do not require an entity to be defined.
— end note
 ]
A case or default label appearing within such an if statement shall be associated with a switch statement within the same if statement.
A label declared in a substatement of a constexpr if statement shall only be referred to by a statement in the same substatement.
Example
:
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
}

extern int x;       // no definition of x required

int f() {
  if constexpr (true)
    return 0;
  else if (x)
    return x;
  else
    return -x;
}
— end example
 ]
An if statement of the form
if constexpr ( init-statement condition ) statement
is equivalent to
{
	init-statement
	if constexpr ( condition ) statement
}
and an if statement of the form
if constexpr ( init-statement condition ) statement else statement
is equivalent to
{
	init-statement
	if constexpr ( condition ) statement else statement
}
except that names declared in the init-statement are in the same declarative region as those declared in the condition.
In other words, the else is associated with the nearest un-elsed if.

8.5.2 The switch statement [stmt.switch]

The switch statement causes control to be transferred to one of several statements depending on the value of a condition.
The condition shall be of integral type, enumeration type, or class type.
If of class type, the condition is contextually implicitly converted to an integral or enumeration type.
If the (possibly converted) type is subject to integral promotions, the condition is converted to the promoted type.
Any statement within the switch statement can be labeled with one or more case labels as follows:
case constant-expression :
where the constant-expression shall be a converted constant expression of the adjusted type of the switch condition.
No two of the case constants in the same switch shall have the same value after conversion.
There shall be at most one label of the form
default :
within a switch statement.
Switch statements can be nested; a case or default label is associated with the smallest switch enclosing it.
When the switch statement is executed, its condition is evaluated.
If one of the case constants has the same value as the condition, control is passed to the statement following the matched case label.
If no case constant matches the condition, and if there is a default label, control passes to the statement labeled by the default label.
If no case matches and if there is no default then none of the statements in the switch is executed.
case and default labels in themselves do not alter the flow of control, which continues unimpeded across such labels.
To exit from a switch, see break.
Note
:
Usually, the substatement that is the subject of a switch is compound and case and default labels appear on the top-level statements contained within the (compound) substatement, but this is not required.
Declarations can appear in the substatement of a switch statement.
— end note
 ]
A switch statement of the form
switch ( init-statement condition ) statement
is equivalent to
{
	init-statement
	switch ( condition ) statement
}
except that names declared in the init-statement are in the same declarative region as those declared in the condition.