2012-11-13 73 views
9

當我做這樣的事情:C++ 11基於範圍的for循環如何知道數組大小?

int my_array[5] = {1, 2, 3, 4, 5}; 
for (int &x : my_array) { 
    x *= 2; 
} 

C++ 11顯然知道,我的數組只有5個元素。這些信息是否存儲在my_array對象的某個地方?

如果是這樣,是否有充分的理由說明爲什麼它不能作爲開發人員使用(或者它是?!?!?)?看來,如果C++開發人員總是知道他們正在處理的數組的範圍,那麼世界上的許多問題都將得到解決。

回答

11

這只是語言需要工作的東西,編譯器必須實現。很明顯,my_array的完整類型是int[5](即尺寸是類型的一部分),所以這個信息是容易獲得的。

流行的看法相反,有沒有使用在遊戲中自由std::begin()/std::end()功能,雖然這些會天真地似乎是能夠做的伎倆(但有涉及ADL一抓,將打破這種做法) 。

+0

確定。那麼爲什麼my_array.size不存在有什麼特別的原因? – MrFox

+6

@suslik:當然,因爲數組不是類的類型,因此不能有成員函數。但是你可以簡單地編寫一個產生所需值的'array_size'自由函數模板,或者使用容易製作的['std :: extent'](http://en.cppreference.com/w/cpp/types/extent )。 –

+0

我是如何過這麼久才知道這麼久的......我怪std :: vector :)。 – MrFox

5

不,它不是對象的一部分。但它是這種類型的一部分。這就是數組聲明中的5。然而,這是不行的:

void f(int arr[5]) { 
    for(int& x: arr) { 
     // whatever 
    } 
} 

因爲數組的名字在這裏衰變成一個指針,它的第一個元素,即,參數聲明等效於int *arr不具有大小信息。

+3

在這種情況下,我不會使用術語「衰變」。我認爲該術語通常特定於在許多表達式中對數組變量所做的隱式轉換。 'int a [5]; a + 1; // decay'相反,我喜歡用「調整」一詞來表示這裏發生的事情,因爲這是標準使用的詞。 void foo(int a [5]); //輸入'adjustment':相當於void foo(int * a)'。我說這個詞時,我喜歡用諷刺的語調。 – bames53

+0

雖然這會工作。 'void f(int(&arr)[5]){...}' – balki

+0

作爲參考,@ balki的解決方案不適用於未定義的數組引用。 '(ARR)[5]'。但通常可以通過使用數組大小​​作爲模板參數來處理泛型大小的數組:請參閱https://stackoverflow.com/questions/26182907/range-based-for-loop-on-array-passed-非主要功能 – andybuckley

6

它可用 - 您可以在標準C++的數組上定義beginend。數組的大小以類型編碼。

一般的方法是使用對數組的引用。

下面是一個例子大小功能:

template<typename T, size_t N> 
size_t array_size(T (& const)[N]) 
{ 
    return N; 
} 
+6

這也被稱爲'std :: extent'。已經爲標準庫中的數組定義了「std :: begin」和「std :: end」。 –

相關問題