次のコードサンプルでは、if
ステートメントはbool
コンパイル時定数であるテンプレートパラメーターに依存しています。コンパイラはこのコードを別の方法で処理します。
MSVCはリンクエラーで失敗します(これは私が予想したことです)。
else
ブランチのテンプレート関数にはtrue
テンプレートパラメーター値の特殊化がないため(呼び出されることはありません)。GCCとClangはどちらも問題なくコンパイルされ、実行時の動作は正しいです。これは
if
、コンパイル時にステートメントを評価し、リンクする前に未使用のブランチを削除するためです。
問題は、どの動作が標準に準拠しているか(または、未定義の動作であり、どちらも独自の方法で正しいか)です。
#include <iostream>
template<const bool condition>
struct Struct
{
void print()
{
if (condition)
{
std::cout << "True\n";
}
else
{
printIfFalse();
}
}
private:
void printIfFalse();
};
template <>
void Struct<false>::printIfFalse()
{
std::cout << "False\n";
}
int main()
{
Struct<true> withTrue{};
withTrue.print();
Struct<false> withFalse{};
withFalse.print();
return 0;
}
どちらのコンパイラも正しいです。経験上、これは不特定の動作です。C ++標準では、ここで何が行われるかを指定していません。
—
Sam Varshavchik
@SamVarshavchikさらに一言で言えば、未定義の動作(UB)です。しかし、現実の世界では、それはエラーであるか、機能します。実行時にUBはありません。
—
curiousguy
if constexpr