为什么std :: cout可转换为void *如果使用g ++? [英] why is std::cout convertible to void* if using 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;
。
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屋!