2012-08-09 64 views
12

我意識到下面的GCC 4.7編譯罰款:我可以將0分配給shared_ptr嗎?爲什麼?

#include <memory> 

int main() { 
    std::shared_ptr<int> p; 
    p = 0; 
} 

但是,從intint*沒有賦值運算符,並有從任intint*要麼沒有隱式構造函數。有一個來自int*的構造函數,但那個是明確的。我檢查了標準庫的實現,並且構造器確實是明確的,並且沒有看到任何可疑的賦值操作符。

該程序是否實際上格式良好或是GCC與我混淆?

+4

'0'是特殊文字,它轉換爲'nullptr_t' – Abyx 2012-08-09 17:18:00

+2

@LucDanton這是因爲g ++非常聰明,並且將'42 - 42'轉換爲'0'。在Clang,IIRC發生了同樣的事情(發生了?),在GN2012 – Abyx 2012-08-09 17:20:35

+5

@Abyx上提到過,你錯過了這一點 - '0'沒有特別的處理作爲該語言的文字。 – 2012-08-09 17:25:07

回答

16

這工作的原因是從標準此短報價:

§4.10 [conv.ptr] p1

空指針常數爲積分常量表達式(5.19)的整數類型的prvalue計算結果爲零或類型std::nullptr_t的價值。 [...]整數類型的空指針常量可以轉換爲std::nullptr_t類型的prvalue。 [...]

std::shared_ptr具有std::nullptr_t隱式構造的事實:

§20.7.2.2 [util.smartptr.shared] p1

constexpr shared_ptr(nullptr_t) : shared_ptr() { }

這也使得這樣的怪事:

#include <memory> 

void f(std::shared_ptr<int>){} 

int main(){ 
    f(42 - 42); 
} 

Live example.

+7

關於42-42這些奇怪的東西是空指針常量,這很可能會消失,而且[只有文字0將是一個有效的空指針常量](http://www.open-std.org/jtc1/sc22/wg21/ docs/cwg_active.html#903),在未來的C++版本中。 – hvd 2012-08-09 17:29:33

+0

@ hvd:有趣的,謝謝你! – Xeo 2012-08-09 17:32:17

0

您只能將共享指針分配給另一個共享指針實例。指定shared_pointer保存的類型是不可能的。據我所知這是運營商唯一的過載:

shared_ptr& operator=(const shared_ptr& r);

你正在做什麼是分配0(在這種情況下等於NULL)的指針,而不是類型的值。您輸入的內容在代碼中尚未初始化。

+0

這並沒有真正解決這個問題:「爲什麼編譯器接受這個沒有抱怨」 – Flexo 2012-08-09 17:21:22

相關問題