class my_bool {
private:
bool value;
public:
my_bool(bool value) : value(value) {}
explicit operator bool() { return value };
friend my_bool operator==(const my_bool & instance_1, const my_bool & instance_2);
friend my_bool operator&&(const my_bool & instance_1, const my_bool & instance_2);
};
void main(){
my_bool a = true;
bool b = false;
if(a == b){
// do something
}
if(a && b){
// do something
}
}
我刚刚在binary operator overloading; implicit type conversion创建了一个关于我的问题的类似主题。我可以删除它,因为它对我遇到的问题不够明确。
为什么operator==
工作正常,operator&&
导致含糊不清?我该如何解决这个问题?我当然可以写下operator&&
(bool
,my_bool
),(my_bool
,bool
)的两个重载。这是一个混乱的解决方案
答案 0 :(得分:5)
内置operator&&
是一个上下文,表达式从上下文转换到bool
。其他此类上下文包括例如if
,for
,while
和条件运算符?
的条件。
引用N4296, §4/4(C ++ 14之前的最新公开草案):
某些语言结构要求将表达式转换为布尔值。表达式
e
出现在这样的背景中的人被称为在上下文中被转换为bool
并且当且仅当如此 对于一些发明的临时变量bool t(e);
(8.5),声明t
格式正确。
基本上,这意味着有一个"明显转换为bool
"在这些情况下。或者,为了进一步说明这一点,您可以认为以下两行是同一个:
a && b
static_cast<bool>(a) && static_cast<bool>(b)
因此,编译器在为explicit operator bool()
执行重载解析时必须考虑operator&&
,但在对operator==
执行重载解析时必须忽略它(因为该运算符不强制执行& #34; bool
context&#34; ..你也可以比较数字,字符串......)。
您的案例中的解决方案是IMO一起摆脱operator&&(const my_bool&, const my_bool&)
。毕竟,它不会产生比依赖内置operator&&(bool, bool)
更有意义的行为。 建立第二个&#34;布尔上下文&#34;只是不是为设计的语言(见下文)。
如果你想保留这个操作符,比如说有些副作用,那么我会看到这些选择:
在呼叫网站上明确说明。那就是:
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;
}
结果可以使用CRTP建立一个布尔上下文&#34;
#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)
答案 1 :(得分:1)
我首先想到的是编译器的内置operator&&
的参数是(bool, bool)
,因此可以调用my_bool的显式bool运算符 - 因为你有效,请求显式转换。
但是,我无法在标准中找到关于变量是否出现在&amp;&amp;的右侧的参考文献。应该调用显式转换为bool。
这是apple clang的完整错误输出(上面的源代码修复后):
./nod.cpp:45:10: error: use of overloaded operator '&&' is ambiguous (with operand types 'my_bool' and 'bool')
if(a && b){
~ ^ ~
./nod.cpp:33:20: note: candidate function
friend my_bool operator&&(const my_bool & instance_1, const my_bool & instance_2);
^
./nod.cpp:45:10: note: built-in candidate operator&&(_Bool, _Bool)
if(a && b){
^
1 error generated.
那我该如何解决呢?
删除用户定义的&amp;&amp;操作
class my_bool {
private:
bool value;
public:
my_bool(bool value) : value(value) {}
explicit operator bool() { return value; }
friend my_bool operator==(const my_bool & instance_1, const my_bool & instance_2);
// friend my_bool operator&&(const my_bool & instance_1, const my_bool & instance_2);
};
int main(){
my_bool a = true;
bool b = false;
if(a == b){
// do something
}
if(a && b){
// do something
}
}
答案 2 :(得分:0)
代码bellow对于==和&amp;&amp;同样适用。 仅当类型相同时才会触发类相等。
#include <stdio.h>
class my_bool {
private:
bool v{false};
public:
my_bool() : v(v) {};
operator bool (){return v;}
friend bool operator==(const my_bool a, my_bool b){
printf("operator==\n");return a.v==b;
}
friend bool operator&&(const my_bool a, my_bool b){
printf("operator&&\n");return a.v&&b;
}
};
int main(int argc, char **argv)
{ printf("Starting\n");
bool a=true,b=true;
my_bool A{},B{},R{};
a==b;a&&b;
a==A;a&&A;
A==b;A&&b;
A==B;A&&B;
}