为什么可以将std::ostream转换为void指针?我不知道在std::ostream中有任何这样的转换操作符。代码如下
#include <iostream>
int main()
{
void *p = std::cout; // why does this work?
}我问这个问题是因为我看到一个名为new的放置操作符被调用为
Foo* pFoo = new (std::cerr) Foo;完全不知道为什么要写这样的东西。
PS:我正在用g++ 4.9.2编译,不管有没有-std=c++11。clang++ 不接受代码。
PSS:发现由于所谓的“安全bool问题”(请参阅@nice字节的答案),在C++11前为std::ostream定义了一个void*转换操作符,然后在C++11中删除它。然而,我的代码在使用g++的C++11中编译得很好。更重要的是,clang++拒绝它,无论我使用哪个版本的标准,即使使用-std=c++98,尽管我的理解是,如果编译为pre++11,它应该接受。
发布于 2015-01-21 05:37:46
阅读这 (您的问题在最后一节“安全bool问题”中得到了回答)。
为了更详细地说明一下,这个实现定义了一个隐式的void*转换,它是为std::cin和std::cout这样的东西定义的,这样就可以像while(std::cin>>x){...}这样的代码进行编译,而像int x = std::cin;这样的代码就不能编译了。这仍然是个问题,因为您可以在示例中编写类似的东西。
C++11通过引入显式转换来解决这个问题。
显式转换运算符如下所示:
struct A {
explicit operator B() { ... } // explicit conversion to B
};当A显式转换为B时,这样的代码就合法了:
A a;
B b(a);但是,这样的代码不是:
A a;
B b = a;像if(std::cin)这样的构造需要将cin转换为bool,标准声明为了使转换在特定情况下有效,像bool x(std::cin);这样的代码应该是“合法的”。这可以通过向bool添加显式转换来实现。它允许cin/cout在上述上下文中使用,同时避免类似int x = std::cout;之类的内容。
有关更多信息,请参考比昂氏页和这个问题。
发布于 2015-01-21 15:38:47
只回答后续的问题,因为好字节的答案对于最初的问题是完美的。
很可能的情况是,您的gcc被设置为使用libstdc++ (由于它是ABI中断的更改,它还没有改变运算符),而您的clang被设置为使用libc++ (从一开始就打算作为C++11标准库,在C++98模式下不完全符合--它提供了一个在C++11中显式的bool转换操作符)。
发布于 2015-01-21 05:32:52
我认为应该允许使用if (std::cout) ...,而不允许隐式转换到bool,或者类似的东西。
https://stackoverflow.com/questions/28060250
复制相似问题