如果使用 g++,为什么 std::cout 可以转换为 void*?

why is std::cout convertible to void* if using g++?

为什么可以将 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:我在使用或不使用 -std=c++11 的情况下使用 g++ 4.9.2 进行编译。 clang++ 不接受代码.

PSS:发现由于所谓的 "safe bool problem"(参见@nicebyte 的回答),在 C++11 之前的版本中,为 [ 定义了一个 void* 转换运算符=13=],然后在 C++11 中删除。但是,我的代码在 C++11 中使用 g++ 编译得很好。更重要的是,无论我使用什么版本的标准,clang++ 都会拒绝它,即使使用 -std=c++98,尽管我的理解是如果编译为 pre-C++11 它应该接受。

我认为它允许 if (std::cout) ... 而不允许隐式转换为 bool 或类似的东西。

阅读this(你的问题在最后一节“安全布尔问题”中得到了回答)。

详细说明一下,该实现定义了一个隐式转换为 void*,为 std::cinstd::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); 应该是 "legal"。这可以通过向 bool 添加显式转换来实现。它允许在上面的上下文中使用 cin/cout,同时避免像 int x = std::cout;.

这样的事情

有关详细信息,请参阅 Bjarne's page as well as this question

只回答后续问题,因为 nicebyte 的回答非常适合原问题。

很有可能,您的 gcc 设置为使用 libstdc++(由于它是 ABI 破坏性更改,因此尚未更改运算符),并且您的 clang 设置为使用 libc++(从一开始就是这样)旨在作为 C++11 标准库,在 C++98 模式下不太符合 - 它提供了一个在 C++11 中显式的 bool 转换运算符。