2014-07-20 37 views
2

下面是一個小腳本,打印n = 1,...,20的數字1到n的和。編譯時未知尺寸的數組類的實例化

#include <iostream> 
#include <array> 

using namespace std; 

int test(int n) 
{ 
    array<int,n> myArray; 

    for (int iii = 0; iii < n; iii++) 
     myArray[iii] = iii+1; 

    int nSum; 

    for (int iii = 0; iii < n; iii++) 
     nSum += myArray[iii]; 

    return nSum; 
} 


int main() 
{ 
    for (int n = 1; n <= 20; n++) 
     cout << test(n) << endl; 

    return 0; 
} 

當然,這不會編譯:

Main.cpp: In function ‘int test(long unsigned int)’: 
Main.cpp:9:13: error: ‘n’ is not a constant expression 
    array<int,n> myArray; 
     ^
Main.cpp:9:13: note: in template argument for type ‘long unsigned int’ 
Main.cpp:9:22: error: invalid type in declaration before ‘;’ token 
    array<int,n> myArray; 
       ^
Main.cpp:11:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] 
    for (int iii = 0; iii < n; iii++) 
        ^
Main.cpp:12:14: error: invalid types ‘int[int]’ for array subscript 
    myArray[iii] = iii+1; 
     ^
Main.cpp:16:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] 
    for (int iii = 0; iii < n; iii++) 
        ^
Main.cpp:17:22: error: invalid types ‘int[int]’ for array subscript 
    nSum += myArray[iii]; 
       ^
make: *** [Main.o] Error 1 

的問題似乎是(除其他事項外),其n不是一個常量表達式,我明白爲什麼這是一個問題,但我不知道如何解決它。

我知道如何用新函數實例化「常規」數組,但我不明白數組類如何可能。

如何使test函數將n視爲常量?

+2

這就是'std :: vector'的用途。 – leemes

回答

4

基本上有兩種選擇。

  1. 正如你已經提到的,std::array需要一個編譯時的大小。因此,請在編譯時將其告知!這可以通過將其轉換爲模板參數來完成。

    變化

    int test(int n) 
    

    template<int n> 
    int test() 
    

    的問題是,它則必須與test<n>()代替test(n)被調用,這又需要在調用者的代碼n在編譯被稱爲當然,這與for -loop不一樣。如果你在編譯期間知道你的循環的上限(就像在你當前的代碼片段中那樣),它可以完成,但它有點複雜。如果不知道,即用戶輸入,則根本無法使用該解決方案。

    所以這不是一個好的選擇。

  2. 不要使用std::array但並不需要在編譯時的大小,但在運行的容器類型。正如你所提到的,堆分配的原始數組(new int[n])是一個選項,但它不是非常的C++ - ish。 使用std::vector代替

    對於這一點,只需更改

    array<int,n> myArray; 
    

    vector<int> myArray(n); 
    

    PS。在未來,可能會有std::dynarray (proposed container type),這恰好符合std::vector目前的要求。它反映了new int[n]的用途,其中n在運行時已知,但在陣列的生命週期中保持不變,填補了std::arraystd::vector之間的差距。然而在幾乎所有情況下,std::vector都可以做得很好!

+0

這是一個很好的答案,儘管上面可能需要澄清一下,目前沒有辦法解決我的問題,我無法以任何方式將'n'視爲常量。 – Undreren

+0

另外,這是不可能的原因,因爲模板是一個「編譯技巧」?難道我在技術上不得不在運行時(這是不可能的)爲編譯我的方法工作的新版本的數組? – Undreren

+0

在Rapperswil(2014年6月)的ISO C++會議上閱讀了一些旅行報告之後,「dynarray」很快就不會再被添加了。沒有確切的答案,關於它的問題太多了。 – pmr

1

您可以改爲使用vector;

#include <vector> 

vector<int> myArray (n); // n zero-initialized elements 

像你正在使用的陣列使用operator[]