隐式转换为布尔值并与布尔文字进行比较

时间:2014-01-25 13:58:30

标签: c++ c++11

我正在回答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 )这样的条件失败了(ffoo。我自己尝试过这个并且让我感到惊讶,因为与布尔文字的比较会导致转换为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的行为示例。

3 个答案:

答案 0 :(得分:2)

由于foo是类类型,因此在使用未针对该类类型明确定义的运算符时应用特殊规则,请参阅[over.built] / 12

  

对于每对提升的算术类型LR,存在形式的候选运算符函数

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是类型LR之间通常的算术转换的结果。

不使用术语提升的算术类型:这需要促销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.1clang++3.5会报告这种歧义。 (应该注意clang可能有一个错误,请参阅this example,它适用于g ++ 4.8.1。)


但是,没有形式的候选人

common_type<bool, int> operator==(bool, int);

因为bool 不是推荐的算术类型。因此,从foobool的转换将为表达式选择而不是

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

而我的猜测是,这种推广恰好在这里发生