組み込みoperator&&
は式は文脈bool
にに変換されるコンテキストです。他のそのような状況は、例えば、if
,for
,while
および条件付き演算子?
の条件を含む。
特定の言語構造は、式はブール値に変換する必要が:N4296, §4/4(C++ 14の前に、最新の公に利用可能な案を)引用
。そのような文脈に現れる表現e
は、文脈上bool
に変換されたと言われており、 宣言bool t(e);
が整形式である場合にのみ、整形式変数t
(8.5)の場合に整形式となる。
基本的に、これは、これらのコンテキストで「暗黙の明示的な変換をbool
にする」ことを意味します。それとも、これをさらに説明するために、次の2つの行が1と同じであることを考えることができます。
a && b
static_cast<bool>(a) && static_cast<bool>(b)
そのため、コンパイラはoperator&&
のためのオーバーロードの解決を行うときexplicit operator bool()
を検討したが、やってたときに、それを無視している必要がありますoperator==
の過負荷解決(演算子は "bool
コンテキスト"を強制しないので、数値、文字列なども比較できます)。
あなたのケース内の溶液はすべて一緒operator&&(const my_bool&, const my_bool&)
を取り除くためにIMOです。結局のところ、組み込み関数operator&&(bool, bool)
に頼ることによって可能なものよりも意味のある動作を生成しません。 2番目の「ブール値のコンテキスト」を確立することは、言語が(以下を参照)用に設計されたものではありません。
あなたがこの演算子を保持したい場合は、私はこれらの選択肢を参照してください、いくつかの副作用のために言う:
は、呼び出しサイトで明示して下さい。それは次のとおりです。
if (static_cast<my_bool>(a) && static_cast<my_bool>(b)) { /* ... */ }
は定義サイトで明示して:operator&&(my_bool const &, bool)
、operator&&(bool, my_bool const &)
のための追加的な定義を提供します。これらは、operator&&(my_bool const &, my_bool const &)
とoperator&&(bool, bool)
の両方を除外する必要があります。これは、あまり具体的でないためです。あなたのクラスshould mitigate the issueにこれらの定義を追加:
friend my_bool operator&&(const my_bool & lhs, bool rhs) {
// Delegate to operator&&(const my_bool &, const my_bool &)
return lhs && my_bool(rhs);
}
friend my_bool operator&&(bool lhs, const my_bool & rhs) {
// Delegate to operator&&(const my_bool &, const my_bool &)
return my_bool(lhs) && rhs;
}
は1つがCRTPを使用して、 "ブール値コンテキストを確立" することができ判明:
#include <iostream>
using namespace std;
template<typename T>
struct bool_context {
friend T operator&&(T const & lhs, bool rhs) {
return lhs && T(rhs);
}
friend T operator&&(bool lhs, T const & rhs) {
return T(lhs) && rhs;
}
friend T operator||(T const & lhs, bool rhs) {
return lhs || T(rhs);
}
friend T operator||(bool lhs, T const & rhs) {
return T(lhs) || rhs;
}
};
struct my_bool : bool_context<my_bool> {
bool value;
my_bool(bool v) : value(v) {}
explicit operator bool() { return value; };
friend my_bool operator&&(my_bool const & lhs, my_bool const & rhs) {
cout << "my_bool::operator&&" << endl;
return lhs.value && rhs.value;
}
friend my_bool operator||(my_bool const & lhs, my_bool const & rhs) {
cout << "my_bool::operator||" << endl;
return lhs.value || rhs.value;
}
};
int main(int, char**) {
my_bool a = true;
bool b = false;
cout << "a && b => "; a && b; // my_bool::operator&&
cout << "b && a => "; b && a; // my_bool::operator&&
cout << "a && a => "; a && a; // my_bool::operator&&
cout << "b && b => "; b && b; cout << endl;
cout << "a || b => "; a || b; // my_bool::operator||
cout << "b || a => "; b || a; // my_bool::operator||
cout << "a || a => "; a || a; // my_bool::operator||
cout << "b || b => "; b || b; cout << endl;
return 0;
}
(Ideone)
'void main()' *いいえ*。 'int main()' –
なぜなら、 '&&'は、引数が文脈上bool *に変換され、 'explicit'とマークされたコンバータを許可するコンテキストであるからです。 '?'、 '||'、 '?'、 '' do''、 'while'、' static_assert'、 'noexcept'の最初のオペランド –
実際に' explicit'キーワードが表示され、 'my_bool'から' bool'への暗黙の変換は許されません。そのような変換は、明示的に '(bool)my_bool_instance'だけ行うことができます。つまり、コンパイラは 'my_bool'を暗黙の変換にboolすることを考慮しないでください。 – user3600124