if-else ステートメント (C++)
if-else ステートメントでは、条件分岐が制御されます。 内の if-branch
ステートメントは、0 以外の condition
値 (または true
) に評価された場合にのみ実行されます。 condition
の値が 0 以外の場合は、次のステートメントが実行され、省略可能な else
の後のステートメントはスキップされます。 それ以外の場合は、次のステートメントがスキップされ、else
がある場合は、else
の後のステートメントが実行されます。
condition
0 以外と評価される式は次のとおりです。
true
- null 以外のポインター。
- 0 以外の算術値、または
- 算術型、ブール型、またはポインター型への明確な変換を定義するクラス型。 変換については、「標準変換」を参照してください。
構文
init-statement
:
expression-statement
simple-declaration
condition
:
expression
attribute-specifier-seq
optdecl-specifier-seq
declarator
brace-or-equal-initializer
statement
:
expression-statement
compound-statement
expression-statement
:
expression
opt;
compound-statement
:
{
statement-seq
opt}
statement-seq
:
statement
statement-seq
statement
if-branch
:
statement
else-branch
:
statement
selection-statement
:
if
constexpr
opt17(
init-statement
opt17condition
)
if-branch
if
constexpr
opt17(
init-statement
opt17condition
)
if-branch
else
else-branch
17 この省略可能な要素は、C++17 から使用できます。
if-else ステートメント
if
ステートメントのすべての形式で、構造体以外の任意の値を持つことができる condition
が、すべての副作用を含めて評価されます。 実行された if-branch
または else-branch
に、break
、continue
、または goto
が含まれていない場合、制御は if
ステートメントからプログラム内の次のステートメントに渡されます。
if...else
ステートメントの else
句は、対応する else
ステートメントがない同じスコープ内の直前の if
ステートメントに関連付けられます。
例
このサンプル コードでは、else
を指定した場合と指定しない場合の両方について、使用されている if
ステートメントがいくつか示されています。
// if_else_statement.cpp
#include <iostream>
using namespace std;
int main()
{
int x = 10;
if (x < 11)
{
cout << "x < 11 is true!\n"; // executed
}
else
{
cout << "x < 11 is false!\n"; // not executed
}
// no else statement
bool flag = false;
if (flag == true)
{
x = 100; // not executed
}
int *p = new int(25);
if (p)
{
cout << *p << "\n"; // outputs 25
}
else
{
cout << "p is null!\n"; // executed if memory allocation fails
}
}
出力:
x < 11 is true!
25
初期化子を含む if ステートメント
C++17 以降では、名前付き変数をif
init-statement
宣言して初期化する式をステートメントに含めることもできます。 変数が if ステートメントのスコープ内でのみ必要な場合は、この形式の if ステートメントを使用します。 Microsoft 固有: このフォームは Visual Studio 2017 バージョン 15.3 から使用できます。少なくとも /std:c++17
コンパイラ オプションが必要です。
例
// Compile with /std:c++17
#include <iostream>
#include <mutex>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
map<int, string> m{ {1, "one"}, {2, "two"}, {10,"ten"} };
mutex mx;
bool shared_flag = true; // guarded by mx
int getValue() { return 42; }
int main()
{
if (auto it = m.find(10); it != m.end())
{
cout << it->second << "\n";
}
if (int x = getValue(); x == 42)
{
cout << "x is 42\n";
}
if (lock_guard<mutex> lock(mx); shared_flag)
{
cout << "setting shared_flag to false\n";
shared_flag = false;
}
string s{ "if" };
if (auto keywords = { "if", "for", "while" }; any_of(keywords.begin(), keywords.end(), [&s](const char* kw) { return s == kw; }))
{
cout << "Error! Token must not be a keyword\n";
}
}
出力:
ten
x is 42
setting shared_flag to false
Error! Token must not be a keyword
if constexpr ステートメント
C++17 より、関数テンプレートで if constexpr
ステートメントを使用すると、複数の関数オーバーロードにアクセスすることなく、コンパイル時の分岐を決定できます。 Microsoft 固有: このフォームは Visual Studio 2017 バージョン 15.3 から使用できます。少なくとも /std:c++17
コンパイラ オプションが必要です。
例
この例では、送信された型に基づいてテンプレートを条件付きでコンパイルする方法を示します。
// Compile with /std:c++17
#include <iostream>
template<typename T>
auto Show(T t)
{
//if (std::is_pointer_v<T>) // Show(a) results in compiler error for return *t. Show(b) results in compiler error for return t.
if constexpr (std::is_pointer_v<T>) // This statement goes away for Show(a)
{
return *t;
}
else
{
return t;
}
}
int main()
{
int a = 42;
int* pB = &a;
std::cout << Show(a) << "\n"; // prints "42"
std::cout << Show(pB) << "\n"; // prints "42"
}
ステートメントは if constexpr
コンパイル時に評価され、コンパイラは関数テンプレートに送信された引数の型と一致する分岐のコード if
のみを生成します。 ステートメントを if constexpr
コメントアウトしてステートメントのコメントを if
解除すると、コンパイラは両方の分岐のコードを生成します。 つまり、次のエラーが発生します。
- 呼び出
ShowValue(a);
すと、ステートメントが false でコードが実行されない場合if
でも、ポインターではないのでエラーreturn *t
t
が発生します。 - 呼び出
ShowValue(pB);
すと、ステートメントが true でコードが実行されない場合if
でも、ポインターであるためt
にエラーreturn t
が発生します。
関数 if constexpr
テンプレートに送信される引数の型と一致するステートメントのみがコンパイルされるため、この問題は解決されます。
出力:
42
42
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示