C++11からはユーザ定義変換に対してexplicit指定ができ、意図しない暗黙の型変換を抑止できるようになった。一方で「bool
型へのexplicitユーザ定義変換」だけは、記述されている場所に応じて(コンテキストに依存して)自動的にbool
型へと変換される。
class T { //... explicit operator bool() const; // 型T→boolへの変換 }; void func(bool); T t; func(t); // NG: 暗黙的にT→boolへ変換されない func(bool(t)); // OK: 明示的な型変換は許容 if (t) { ... } // OK: "コンテキスト依存"のbool型への変換
C++11(N3337)言語仕様では、下記において“コンテキストに依存したbool
型への変換(contextually converted to bool)”が行われると定義する。平易な表現では、セマンティクス上「真偽値が要求される場所」が列挙されている。
- 論理否定演算子
!
のオペランド(5.3.1/p9) - 論理積演算子
&&
の両オペランド(5.14/p1) - 論理和演算子
||
の両オペランド(5.15/p1) - 条件演算子
? :
の第1オペランド(5.16/p1) - if文の条件式(6.4/p4)
- for文の条件式(6.4/p2,4)
- while文の条件式(6.4/p2,4)
- do文の条件式(6.5.2/p1)
- static_assertの定数式(7/p4)
- 関数に対するnoexpect例外指定の定数式(15.4/p1)
リスト末尾の2箇所では定数式(constant-expression)が要求されるため、bool
型へのユーザ定義変換に対するconstexpr指定が必要。
本機能はC++03策定の翌年、2004年の(PDF)N1592 "Explicit Conversion Operators" が初出となる。(PDF)N2437(revision 3)で明確に "boolean-converted" という単語が導入され、N2462で "contextually converted to bool" に変更されて当時のドラフト文書N2461に登場している。
関連URL