2013-08-18 93 views
9

我剛纔問了關於數組和值初始化的兩個問題herehere。 但有了這個代碼,我迷路了:爲什麼std :: array <int, 10> x不是零初始化的,而是std :: array <int, 10> x = std :: array <int, 10>()似乎是?

#include <iostream> 
#include <iomanip> 
#include <array> 

template <class T, class U = decltype(std::declval<T>().at(0))> 
inline U f1(const unsigned int i) 
{T x; return x.at(i);} 

template <class T, class U = decltype(std::declval<T>().at(0))> 
inline U f2(const unsigned int i) 
{T x = T(); return x.at(i);} 

int main() 
{ 
    static const unsigned int n = 10; 
    static const unsigned int w = 20; 
    for (unsigned int i = 0; i < n; ++i) { 
     std::cout<<std::setw(w)<<i; 
     std::cout<<std::setw(w)<<f1<std::array<int, n>>(i); 
     std::cout<<std::setw(w)<<f2<std::array<int, n>>(i); 
     std::cout<<std::setw(w)<<std::endl; 
    } 
    return 0; 
} 

正如預期的那樣,f1返回任意值作爲其值不爲0初始化。但f2似乎返回獨家零值:

    0     0     0 
        1     61     0 
        2     0     0 
        3     0     0 
        4   297887440     0 
        5    32767     0 
        6    4196848     0 
        7     0     0 
        8   297887664     0 
        9    32767     0 

我個人認爲f2將創建一個任意值和複製的數組/它移到x。但似乎並非如此。

所以,我有兩個問題:

  • 爲什麼?
  • C++ 11 std::array<T, N>和C風格T[N]在這種情況下有相同的行爲嗎?
+3

'T()'是一個值初始化的'T'。如果'T'是C風格的數組類型,則語法無效。 'T x = {};'或'T x {};'是更普遍適用的語法。 – Casey

+0

@Casey值初始化適用於C風格的數組。如果'T'不是一個簡單類型說明符,即一個標識符或一個類型的關鍵字,'T()'是一個語法錯誤。在C++ 03中,'= {}'僅適用於數組,而簡單的'{}'是一個錯誤。 – Potatoswatter

+0

假定的重複是關於值初始化的,但這個問題是關於默認初始化的。請重新打開並找到適當的副本,或者直接回答。 – Potatoswatter

回答

9

使用{}()爲初始化,我們沒有=,結果值初始化。對於具有隱式聲明構造函數的類型,值初始化實現了零初始化,正如其名稱所示,它將每個基本元素設置爲0。這發生在構造函數可能運行之前,但在這種情況下,構造函數什麼都不做。

因爲構造函數什麼都不做(它是微不足道的),所以可以看到未初始化的數據。

至於C風格的陣列,如果您使用= {}而不是= T(),因爲後者是非法的行爲是相似的。 T()會要求將臨時數組對象分配給指定對象,但不能分配數組。另一方面,= {}爲數組指定了一個braced-initializer-list,而一個braced-initializer-list是一個特殊的句法結構,既不是表達也不是對象。

相關問題