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,值为false​0​ 真的变成了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);
as
bool
不是提升的算术类型。因此,表达式不会选择从
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