编译器内部如何识别 io流 需要做 bool 或者 void* 转换的呢?

wangjieest 2012-08-16 10:51:13
想問個問題, IO流的布爾判斷是如何實現的啊。。。
例如 if (cin>>a)。。。
看書上說是 重載 void* 。。。 不是很理解
...全文
209 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangjieest 2012-10-15
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

这个问题似乎争论很多次了,参考这篇(http://topic.csdn.net/u/20120524/10/23f749c2-1d1d-4aa5-a9e6-a9c288cbfe11.html)以前的问答。

引用 9 楼 的回复:

引用 6 楼 的回复:

不建议用cin和cout,printf/scanf/fgets/puts/getchar/putchar等函数要单纯的多。……
[/Quote]

...... 不是C++ iostream的问题...而是,编译器解析的规则
图灵狗 2012-10-15
  • 打赏
  • 举报
回复
这个问题似乎争论很多次了,参考这篇(http://topic.csdn.net/u/20120524/10/23f749c2-1d1d-4aa5-a9e6-a9c288cbfe11.html)以前的问答。

[Quote=引用 9 楼 的回复:]

引用 6 楼 的回复:

不建议用cin和cout,printf/scanf/fgets/puts/getchar/putchar等函数要单纯的多。

大虾能帮忙解释下这个过程么?
[/Quote]
wangjieest 2012-10-15
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

不建议用cin和cout,printf/scanf/fgets/puts/getchar/putchar等函数要单纯的多。
[/Quote]
大虾能帮忙解释下这个过程么?
wangjieest 2012-10-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

用于布尔值表示法的操控器:
boolalpha 强制使用文字表示
noboolalpha 强制使用数字表示

C/C++ code
bool flag;

cin >> std::noboolalpha >> flag;
cout << std::boolalpha << flag << std::endl;
[/Quote]

文不对题,我意思是 if(cin)这个判断的编译器是如何转换的...
wangjieest 2012-10-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

充分说明操作符重载是语法糖。
摒弃cin;使用scanf并检查其返回值。
[/Quote]
赵老师没有说在要点上...
图灵狗 2012-10-15
  • 打赏
  • 举报
回复
不建议用cin和cout,printf/scanf/fgets/puts/getchar/putchar等函数要单纯的多。
xyddz 2012-10-15
  • 打赏
  • 举报
回复
用于布尔值表示法的操控器:
boolalpha 强制使用文字表示
noboolalpha 强制使用数字表示

bool flag;

cin >> std::noboolalpha >> flag;
cout << std::boolalpha << flag << std::endl;

赵4老师 2012-10-15
  • 打赏
  • 举报
回复
充分说明操作符重载是语法糖。
摒弃cin;使用scanf并检查其返回值。
wangjieest 2012-10-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

补充:if (cin)所发生的转换为隐式转换。
[/Quote]
想弄懂这里面的过程,例如什么情况下才会调用这个 void*()转换? 和bool()转换的先后顺序和逻辑....

看参数类型转换的过程有点像,精确匹配-->提升-->标准转换
一个原类型,一个目标类型.
首先看是否是精确匹配,
其次提升后再进行比较,
再次通过标准转换进行比较,
如果还没找到符合的,就认为是匹配失败,不能转换...
先指针到void*() 再由void*()到 bool(),这是两步标准转换,难倒表达式转换的过程可以有多次转换?那它的选择支是怎么样的?

if(cin==true) 恒等于if(cin)?
内部实现是否是这个样子,if (cin!=false) if(cin!=0) 是转换0呢,还是转换cin呢?

可是这个转换过程如果没有重载bool()的时候,却用到了void*(),但是最终结果却还要是bool(),对这点十分迷惑???

说白了,现在就是很疑惑一个 指针和bool值的比较,为什么会有 void*()这一步...
blldw 2012-08-16
  • 打赏
  • 举报
回复
补充:if (cin)所发生的转换为隐式转换。
blldw 2012-08-16
  • 打赏
  • 举报
回复
std::cout和std::cin分别是std::ostream和std::istream类对象。而
std::ostream为:typedef basic_ostream<char, char_traits<char> > ostream;
std::istream为:typedef basic_istream<char, char_traits<char> > istream;

单就basic_istream模板类而言,其具有一系列针对不同操作数类型定义的重载运算符>>,如
basic_istream& operator>>(
basic_istream& (*_Pfn)(basic_istream&)
);
basic_istream& operator>>(
ios_base& (*_Pfn)(ios_base&)
);
basic_istream& operator>>(
basic_ios<Elem, Tr>& (*_Pfn)(basic_ios<Elem, Tr>&))
;
basic_istream& operator>>(
basic_streambuf<Elem, Tr> *_Strbuf
);
basic_istream& operator>>(
bool& _Val
);
basic_istream& operator>>(
short& _Val
);
basic_istream& operator>>(
unsigned short& _Val
);
basic_istream& operator>>(
int& _Val
);
basic_istream& operator>>(
unsigned int& _Val
);
basic_istream& operator>>(
long& _Val
);
basic_istream& operator>>(
unsigned long& _Val
);
basic_istream& operator>>(
void *& _Val
);
basic_istream& operator>>(
float& _Val
);
basic_istream& operator>>(
double& _Val
);
basic_istream& operator>>(
long double& _Val
);

通过返回值可以看到,cin>>a的结果仍为输入流对象的引用,即cin。而
template <class Elem, class Tr = char_traits<Elem> >
class basic_istream
: virtual public basic_ios<Elem, Tr>

其中basic_ios模板类具有一个类型转换符和一个重载运算符函数:
operator void *( ) const;
bool operator!( ) const;

if (cin)和if (!cin)将分别调用operator void*() const;和bool operator!() const;前者将cin转换为指针类型,如果cin的状态为fail,则返回null指针,否则转换为有效的地址,二者都可以转换为bool。后者就比较明显了。

希望对楼主理解有帮助。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧