如果使用 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::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);
应该是 "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 转换运算符。
为什么可以将 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::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);
应该是 "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 转换运算符。