【问题标题】:Converting false to pointer type void*?将 false 转换为指针类型 void*?
【发布时间】:2017-10-07 11:17:31
【问题描述】:

谁能解释一下这里发生了什么...?

我有这个代码:

#include <fstream>
#include <string>
#include <iostream> 
int main(){   
    std::ifstream file("test.txt");    
    std::string x;
    while (true) { 
        if (!(file >> x)) return 0;
        std::cout << x << "\n";   
    }
}

...编译得很好,做它应该做的,到目前为止没有问题。有时候我不太喜欢!,因为它很容易被忽略,所以我把if换成了

if ((file >> x)==false) return 0;  

..突然我的编译器 (gcc 4.8.5) 发出警告:

 warning: converting ‘false’ to pointer type ‘void*’ [-Wconversion-null]
     if ((file >> x)==false) return 0;

这就是我开始感到困惑的地方。 void* 来自哪里? &gt;&gt; 不会返回一个应该转换为bool 的引用吗?为什么false 转换为void*?为什么我没有明确写false时没有触发相同的警告?

出于好奇,我也试过这个:

if ((file>>x)==true) return 0;

这会导致以

开头的错误风暴
error: no match for ‘operator==’ (operand types are ‘std::basic_istream<char>’ and ‘bool’)
 if ((file>>x)==true) return 0;
              ^

现在我完全迷路了。 falsebooltrue 有何不同?当然不同的值,但我一直认为truefalse是同一类型。

【问题讨论】:

  • void * 重载已在 C++11 中删除,我建议使用现代 C++
  • @M.M 你确定吗?使用-std=c++11 编译时,我得到完全相同的警告。也许 gcc 忘了删除它
  • 听起来像是编译器错误

标签: c++ stream boolean type-conversion


【解决方案1】:

回想一下,C++ 有运算符重载。特别是std::basic_istreamoverloads operator!

唉,没有强制运算符重载在语义上是一致的,因此==istreambool 之间没有重载。因此与true 的比较失败。但是,编译器也可以应用隐式转换来编译表达式——在这种情况下,false 可以隐式转换为空指针,basic_istream 有一个overload of operator void*(尽管显然它被替换为operator bool 在 C++11 中 - 可能是为了修复不一致)。

【讨论】:

  • 好的,第一个谜团已解决。 ==false 一起工作但与true 不一起工作呢? Afaik 重载是关于类型而不是值
  • @tobi303 - 啊,我没有看到问题的第二部分。将添加更新。
  • .....false 可以转换成nullptr 但是true 没有这样的转换,是这样吗?
  • @tobi303 - 没错,就是这样。
  • 您是否介意添加您的答案,static_cast&lt;bool&gt; 可以完全避免该问题(false 没有警告,true 案例甚至可以)?
猜你喜欢
  • 2021-09-20
  • 1970-01-01
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 2013-04-07
  • 2023-02-26
相关资源
最近更新 更多