【问题标题】:stream output and implicit void* cast operator function invocation流输出和隐式 void* cast 运算符函数调用
【发布时间】:2011-09-10 18:49:26
【问题描述】:

类似的代码

cin>> grade;

其中等级是标准数据类型,返回对启用级联输入的 cin(istream object) 的引用....
但我读到如果

cin >>grade;

用作while 语句中的条件...流的 void* 强制转换运算符函数被隐式调用...它将对 istream 对象的引用转换为非空或空指针,具体取决于成功或失败最后一个输入操作...空指针转换为假,非空转换为真...我的问题是:

  1. 什么是 void * cast 运算符函数以及它在此处如何工作
  2. 非空指针如何转为真,空转为假

【问题讨论】:

  • 请注意为什么这很有用:它允许您像 while(cin >> x) { /* do stuff with x */ } 一样循环。

标签: c++


【解决方案1】:

1.什么是void * cast操作符函数,在这里它是如何工作的

看起来像这样:

operator void* () const {
    return fail() ? 0 : this;
}

问题是:为什么这里不使用operator bool?答案是:因为这允许可能隐藏错误的无效转换。以上是safe bool idiom的一个例子。

然而,这个实现实际上已经过时了。这个成语存在更好的实现;文章解释了它们。

2.非空指针如何转为真,空为假

这正是 C++ 的工作原理:任何非空指针都被认为等同于条件中的true。现在,为什么 C++ 首先在这里调用operator void*

本质上,当 C++ 看到一个意外类型的对象时,它会尝试应用 one 隐式转换,以使对象类型在此上下文中有效。因此,编译器会尝试所有可用的隐式转换,并查看生成的类型在这种情况下是否可以接受。

这发生在她身上:编译器看到while (cin >> grade)。它知道basic_istreamwhile 条件的上下文中无效。所以它发现有一个operator void* 和一个void* 在这个上下文中有效,所以 C++ 应用这个转换。

【讨论】:

  • @Konrad:这还不够 -> return fail() ? 0 : this; ?
  • @Nawaz 不确定,也懒得检查。 ?:禁止不兼容类型之间的隐式转换。也许0 的类型在这里被正确推断为basic_istream*。但无论哪种方式,演员都会明确这一点。
  • @Konrad:是的。由于隐式转换,0 与任何类型的指针兼容。这就是它经常用作任何类型的 NULL 指针的原因。 std::istream *p = 0;std::string *s=0;void* v = 0; 都很好。无论如何,+1 以获得好的答案。
  • @Nawaz 然而,这些是不同的情况,因为它们是初始化。初始化也可以调用隐式转换运算符,?:不能这样做。
  • @avinash 不一定。这只是一个典型的实现。实际上,任何指针值 != 0 都可以,例如 reinterpret_cast<void*>(1)
猜你喜欢
  • 1970-01-01
  • 2012-02-06
  • 2021-05-31
  • 1970-01-01
  • 2014-03-18
  • 2011-07-21
  • 2020-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多