C++ 到布尔值的隐式转换以及与布尔文本的比较
我在回答关于用户定义转换为C++ 到布尔值的隐式转换以及与布尔文本的比较,c++,c++11,C++,C++11,我在回答关于用户定义转换为bool以及如何禁用其他转换的主题: struct foo { operator bool() const //Explicit overload for bool { return true; } template<typename T> operator T() const = delete; //Everithing which is not a bool (Everithing which
bool
以及如何禁用其他转换的主题:
struct foo
{
operator bool() const //Explicit overload for bool
{
return true;
}
template<typename T>
operator T() const = delete; //Everithing which is not a bool (Everithing which
//does not fit in the explicit overload) would
//resolve to this operator and will fail.
};
int main()
{
foo f;
bool b = f; //OK
int i = f; //ERROR
char c = f; //ERROR
etc...
}
prog.cpp:20:12:错误:使用已删除的函数'foo::operator T()
常数[T=int]'if(f==true)()^ 我的问题是:布尔文字是否定义为整数(如常见的C宏
#define true 1#define false 0
),如果不是,为什么比较会导致整数转换而不是bool
?
我正在使用启用了C++11的GCC4.8.1(-std=C++11
)
是IDENN中的行为的一个例子。
类型布尔不是C++中定义的。我认为比较升级为int,需要int转换。
让我们在这里做一个快速测试:template <typename T>
struct OutputType;
int main()
{
OutputType<decltype(true)> a;
}
模板
结构输出类型;
int main()
{
输出类型a;
}
至少ideone在此输出的true
类型为bool
:
然而:
类型bool可以转换为int,值为false0 真的变成了1
资料来源:
我的猜测是,正是这样的提升在这里发生因为
foo
是一种类类型,当使用未专门为该类类型定义的运算符时,会应用特殊规则,请参见[over.build]/12
对于每对提升的算术类型L
和R
,都存在以下形式的候选运算符函数
LR operator*(L, R);
LR operator/(L, R);
LR operator+(L, R);
LR operator-(L, R);
bool operator<(L, R);
bool operator>(L, R);
bool operator<=(L, R);
bool operator>=(L, R);
bool operator==(L, R);
bool operator!=(L, R);
common_type<L,int> operator==(L, int);
common_type<bool, int> operator==(bool, int);
其中,L
是一种提升的算术类型。然而,例如,有很多
common_type<int , int> operator==(int , int);
common_type<long , int> operator==(long , int);
common_type<long long, int> operator==(long long, int);
asbool
不是提升的算术类型。因此,表达式不会选择从foo
到bool
的转换
foo x;
x == true
这就是我所想的,我知道bool文本不是
#define
d。只是这种行为让我惊讶。有人引用过标准吗?布尔值被转换为int进行比较。我没有对标准的引用(需要下载,嗯…),但我很确定bool=>int加上类foo上缺少int转换是错误的根源。我认为答案并不完整。还有一块不见了,我注意到了。我在等待:)@Manu343726缺少的部分是一些语句,其中指出类类型确实需要转换为与升级的bool
相同的类型。这可能有点微妙,例如,内置的操作符==
要求左右两侧的类型相同。@dyp另一个问题是bool操作符==(bool,bool)
是否存在,或者true==true
是否会导致调用bool操作符==(int,int)
@Manu343726这些规则是从C继承的;事实上,他们试图复制硬件的行为。积分促销不仅限于bool
s,还适用于char
s和short
s等。例如,short s=1,t=2;自动x=s+t
将x
声明为int
。注意,在一个相关示例中,两者之间有一个有趣的区别,这可能是标准中的一个缺陷,请参阅(公开发行),尤其是注释“一些实现明确地选择int
候选者。或许可以调整重载解析规则,以选择L和R类型相同的候选项?”(这是我答案中缺少的部分)
foo x;
x == true