为什么std :: cout可转换为void *如果使用g ++? [英] why is std::cout convertible to void* if using g++?

查看:173
本文介绍了为什么std :: cout可转换为void *如果使用g ++?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么可以将 std :: ostream 转换为 void 指针?我不知道在 std :: ostream 中有任何这样的转换操作符。下面的代码

  #include< iostream> 

int main()
{
void * p = std :: cout; //为什么这样工作?
}

我问这个问题,因为我看到一个布局运算符 new 调用为

  Foo * pFoo = new(std :: cerr)Foo ; 

,完全不知道为什么要写这样的东西。



PS:我用g ++ 4.9.2编译,有或没有 -std = c ++ 11 。 clang ++ 不接受代码



PSS:发现由于所谓的安全bool问题 ,在前C ++ 11中为 std :: ostream 定义了 void * 转换运算符,在C ++ 11。然而,我的代码编译在C ++ 11使用g ++罚款。更重要的是,clang ++拒绝它,无论我使用的是什么版本的标准,即使使用 -std = c ++ 98 ,虽然我的理解是,如果编译作为前C ++ 11。

解决方案

阅读(您的问题在最后一节安全bool问题中回答。)



为了阐述一点,实现定义了为 std :: cin定义的隐式转换 void * std :: cout ,只是为了使代码像 while(std :: cin>> x){。 ..} 编译,而像 int x = std :: cin; 的代码不会。它仍然有问题,因为你可以写你的例子中的东西。



C ++ 11通过引入显式转换来解决这个问题。



显式转换运算符如下所示:

  
显式运算符B(){...} //显式转换为B
};

当A显式转换为B时,此类代码变为合法:

  A a; 
B b(a);但是,这样的代码不是:


  A a; 
B b = a;

if(std :: cin)要求将 cin 转换为 bool ,标准规定为了使转换有效特殊情况下,代码如 bool x(std :: cin); 应该是legal。这可以通过向 bool 添加显式转换来实现。它允许在上面的上下文中使用cin / cout,同时避免像 int x = std :: cout;



有关详情,请参阅 Bjarne的页面作为此问题


Why can one cast a std::ostream to a void pointer? I am not aware of any such conversion operator in std::ostream. Code below

#include <iostream>

int main()
{
    void *p = std::cout; // why does this work? 
}

I'm asking this question since I've seen a placement operator new invoked as

Foo* pFoo = new (std::cerr) Foo;

and have absolutely no idea why would one write such a thing.

PS: I am compiling with g++ 4.9.2 with or without -std=c++11. clang++ does not accept the code.

PSS: Found out that due to the so called "safe bool problem" (see @nicebyte's answer), in pre C++11 a void* conversion operator was defined for std::ostream, which was then removed in C++11. However, my code compiles fine in C++11 using g++. More than that, clang++ rejects it no matter what version of the standard I use, even with -std=c++98, although my understanding is that it should accept if compiled as pre-C++11.

解决方案

Read this (your question is answered in the very last section, "The safe bool problem").

To elaborate a bit, the implementation defines an implicit conversion to void* defined for things like std::cin and std::cout, just so that code like while(std::cin>>x){...} compiles, while code like int x = std::cin; doesn't. It's still problematic because you can write stuff like in your example.

C++11 solves this problem by introducing explicit conversions.

An explicit conversion operator looks like this:

struct A {
 explicit operator B() { ... } // explicit conversion to B
};

When A has an explicit conversion to B, code like this becomes legal:

A a;
B b(a);

However, code like this is not:

A a;
B b = a;

A construct like if(std::cin) requires cin to be converted to bool, the standard states that in order for the conversion to be valid in that particular case, code like bool x(std::cin); should be "legal". Which can be achieved by adding an explicit conversion to bool. It allows cin/cout to be used in the above context, while avoiding things like int x = std::cout;.

For more information, refer to Bjarne's page as well as this question.

这篇关于为什么std :: cout可转换为void *如果使用g ++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆