首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么std::cout可转换为无效*如果使用g++?

为什么std::cout可转换为无效*如果使用g++?
EN

Stack Overflow用户
提问于 2015-01-21 05:31:12
回答 3查看 397关注 0票数 13

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

代码语言:javascript
复制
#include <iostream>

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

我问这个问题是因为我看到一个名为new的放置操作符被调用为

代码语言:javascript
复制
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,它应该接受。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-21 05:37:46

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

为了更详细地说明一下,这个实现定义了一个隐式的void*转换,它是为std::cinstd::cout这样的东西定义的,这样就可以像while(std::cin>>x){...}这样的代码进行编译,而像int x = std::cin;这样的代码就不能编译了。这仍然是个问题,因为您可以在示例中编写类似的东西。

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

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

代码语言:javascript
复制
struct A {
 explicit operator B() { ... } // explicit conversion to B
};

当A显式转换为B时,这样的代码就合法了:

代码语言:javascript
复制
A a;
B b(a);

但是,这样的代码不是:

代码语言:javascript
复制
A a;
B b = a;

if(std::cin)这样的构造需要将cin转换为bool,标准声明为了使转换在特定情况下有效,像bool x(std::cin);这样的代码应该是“合法的”。这可以通过向bool添加显式转换来实现。它允许cin/cout在上述上下文中使用,同时避免类似int x = std::cout;之类的内容。

有关更多信息,请参考比昂氏页这个问题

票数 11
EN

Stack Overflow用户

发布于 2015-01-21 15:38:47

只回答后续的问题,因为好字节的答案对于最初的问题是完美的。

很可能的情况是,您的gcc被设置为使用libstdc++ (由于它是ABI中断的更改,它还没有改变运算符),而您的clang被设置为使用libc++ (从一开始就打算作为C++11标准库,在C++98模式下不完全符合--它提供了一个在C++11中显式的bool转换操作符)。

票数 4
EN

Stack Overflow用户

发布于 2015-01-21 05:32:52

我认为应该允许使用if (std::cout) ...,而不允许隐式转换到bool,或者类似的东西。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28060250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档