[英]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:發現由於所謂的“安全布爾問題”(請參閱@nicebyte的答案),在C ++ 11之前的版本中為std::ostream
定義了一個void*
轉換運算符,然后在C ++ 11中將其刪除。 但是,我的代碼使用g ++在C ++ 11中可以正常編譯。 不僅如此,無論我使用什么版本的標准,即使使用-std=c++98
,clang ++都拒絕它,盡管我的理解是,如果編譯為C ++ 11之前的版本,它應該接受。
閱讀此內容 (您的問題將在最后一部分“ 安全的布爾問題 ”中回答)。
詳細說明一下,該實現定義了一個對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;
類的事情int x = std::cout;
。
僅回答后續問題,因為nicebyte的答案非常適合原始問題。
可能是,您的gcc設置為使用libstdc ++(由於它是ABI突破性更改,因此尚未更改運算符),而您的clang設置為使用libc ++(從一開始就打算用作C + +11標准庫,並且在C ++ 98模式下不太符合標准-它提供了布爾轉換運算符,在C ++ 11中是顯式的。
我認為這是允許if (std::cout) ...
而不允許隱式轉換為bool
或類似的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.