@Xeo の優れたc++-faq
質問から: C++11 では safe-bool イディオムは廃止されましたか? explicit
C++03 でセーフ bool が必要なコンテキストでは、ユーザー定義の変換bool
が自動的に呼び出されるため、セーフ bool イディオムが不要になったことを知りました。
&&
ただし、 、 、などの演算子をオーバーロードする機能は、これを回避しているようです||
。!
operator!
への変換の提供を超えて が必要なケースは、やbool
のようにまれですが、C++ 式ツリーの実装 (遅延実行および記号演算手法に使用される) では、これらをオーバーライドする必要があります。operator&&
operator||
ユーザー定義の演算子が呼び出されているときに「コンテキスト変換」が行われますか? operator&&
またはの定義がoperator||
「セーフブール」を実装する型と「コンテキスト変換」用に設計された型の両方で正しく機能することを確認するには、どのような SFINAE 呪文が必要ですか?
明確にするために、与えられた:
class uses_safe_bool
{
void f() {};
typedef void (uses_safe_bool::* safe_bool)();
public:
operator safe_bool() const { return (rand() & 1)? &uses_safe_bool::f: 0; }
};
class uses_explicit_bool
{
public:
explicit operator bool() const { return rand() & 1; }
};
template<typename T>
class deferred_expression
{
// Not convertible to bool
public:
T evaluate() const;
};
operator||
次の式がすべて有効になるために必要な署名は次のとおりです。
deferred_expression<bool> db;
uses_safe_bool sb;
uses_explicit_bool eb;
int i;
auto test1 = sb || db;
auto test2 = eb || db;
auto test3 = true || db;
auto test4 = false || db;
auto test5 = i || db;
これらは異なるオーバーロードを使用します:
auto test6 = db || db;
deferred_expression<int> di;
auto test7 = di || db;
以下はコンパイル時に拒否されます。
std::string s;
auto test7 = s || db;
std::vector<int> v;
auto test8 = v || db;
deferred_expression<std::string> ds;
auto test9 = ds || db;