我正在回答this question,关于用户定义转化为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...
}
后来OP问我为什么像if( f == true )
这样的条件失败了(f
是foo
。我自己尝试过这个并且让我感到惊讶,因为与布尔文字的比较会导致转换为int
(已禁用)而不是bool
:
int main()
{
foo f;
if( f ); //OK, converts to bool
if( f == true ); //ERROR: Conversion to int, which has been disabled
}
prog.cpp:20:12:错误:使用已删除的函数'foo :: operator T() const [with T = int]'if(f == true);
.................................................. .................................................. .......................................... ^
我的问题是:布尔文字是否定义为整数(如常见的C宏#define true 1 #define false 0
),如果不是,为什么这种比较导致int转换而不是bool
?
我正在使用GCC4.8.1并启用了C ++ 11(-std=C++11
)。
Here是ideone的行为示例。
答案 0 :(得分:2)
由于foo
是类类型,因此在使用未针对该类类型明确定义的运算符时应用特殊规则,请参阅[over.built] / 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);
其中
LR
是类型L
和R
之间通常的算术转换的结果。
不使用术语提升的算术类型:这需要促销bool
。
bool
被提升为int
,请参阅[conv.prom] / 6(整体促销)
bool类型的prvalue可以转换为
int
类型的prvalue,false
变为零,true
成为一个。
因此,有
形式的候选函数common_type<L,int> operator==(L, 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);
每个都需要用户定义的从foo
到提升类型的转换。我不清楚为什么这不是模棱两可的,因为foo
可以转换为其中任何一个。这也在未决问题CWG 954中进行了描述。
如果有多个非模板转化函数,g++4.8.1和clang++3.5会报告这种歧义。 (应该注意clang可能有一个错误,请参阅this example,它适用于g ++ 4.8.1。)
但是,没有形式的候选人
common_type<bool, int> operator==(bool, int);
因为bool
不是推荐的算术类型。因此,从foo
到bool
的转换将为表达式选择而不是
foo x;
x == true
答案 1 :(得分:0)
在C ++中输入bool是而不是 #defined。我认为比较提升为int并需要int转换。
答案 2 :(得分:0)
让我们在这里做一个快速测试:
template <typename T>
struct OutputType;
int main()
{
OutputType<decltype(true)> a;
}
此处的Atleast ideone输出true
属于bool
类型:http://ideone.com/Gm653T
但是:
类型bool可以转换为int,值false为0,true为1。
来源:cppreference
而我的猜测是,这种推广恰好在这里发生