2016-08-16 78 views
0

我有m ints和n浮點數,我想在一個循環中迭代它們。爲了做到這一點,我能想到的兩種可能的方式,但我不知道他們實際上是可行的:C++遍歷不同類型的數組

  1. 理想我想給M + N數字存儲在一個陣列(例如,在一個性病:: vector),有沒有一種方法(一個容器,或通過多態性),我可以做到這一點?

  2. 如果我必須將整數和浮點數存儲在兩個數組中,那麼是否存在(或如何編寫)可以在循環中迭代兩個數組的迭代器?

歡迎任何想法!

+0

你可以用'any'來存儲他們,但你需要有一個標誌變量知道從哪裏開始閱讀整數和從哪裏開始閱讀花車,只是將它們放置在兩個數組會SI mpler。 –

+2

爲什麼你想在一個循環中迭代它們? –

+1

我想在一個循環中迭代它們,因爲它會使我的原始程序更簡潔,因爲它可以做同樣的事情,而不管數據類型如何。 – pumpkinjuice

回答

2

這似乎是一個模板函數可能是一個很好的解決方案:

  1. 它保留了語義「做同樣的花車和整數容器的兩個容器」,而不產生的人工容器從性能的角度看節省的代碼
  2. 幾行的緣故彩車/整數會有用手工編碼迭代循環兩個數組在沒有任何區別,如果你讓編譯器的優化-O3
  3. 它適用於其他類型(例如doubleint64_tint32_t等)

它應該是這樣的:

processData(std::vector<float>{1.2, 2.5, 3.5, 4.5}); 
processData(std::vector<int>{1, 2, 3, 4}); 

看到一個working example here

0

可以創建一個結構,並以此作爲你的數組:

struct my_compund_type { 
    int integer; 
    float very_narrow_and_possibly_I_meant_double_float; 
}; 

std::vector<my_compund_type> array; 

你的另一個選擇是for循環,只有遍歷索引,並訪問數組都需要做。

+1

這隻適用於m == n。特別是如果這兩個值在邏輯上不是對(即它們不屬於一對),這將是一個非常誤導性的解決方案...... –

2

有以下幾種:

template<typename T> 
void processData(std::vector<T> data) { 
    for (auto& d : data) { 
    // do some processing 
    } 
} 

你會用它打電話選項,各有其優缺點:

  1. 使用兩個std :: vector,一個用於int,另一個用於float,並將它們迭代到單獨的循環中。如果循環體是非平凡的,把它放到一個模板化的函數中,所以你不必複製代碼。

  2. 使用boost :: any的std :: vector,它可以同時存儲浮點數和整數。獲取該值時,必須將其「投射」爲正確的類型。再次,您可能想將任何邏輯放入模板函數中以避免代碼重複。由於boost :: any轉換爲實際類型涉及類型檢查,因此此解決方案沒有最佳性能。另一方面,它接近Python等運行時類型語言的行爲。

  3. 特別是如果你有更多然後只有兩種類型:使用類型(float和int)的boost :: fusion :: map類型的向量。您可以使用boost :: fusion :: foreach來迭代地圖,它將調用一個模板化函數並將矢量傳遞給它。這樣你就可以獲得第一個解決方案,但這次它對於許多數據類型來說更容易擴展。

由於C++是靜態類型,也沒有辦法有含有浮標和整數無升壓單個容器::任何。例外:如果條目數量在編譯時是固定的,boost :: mpl :: vector可以幫助你。

編輯:如果你想要的代碼示例,給使用更多的信息,你想要去的方式......

1

你可能有不同的因式分解你的代碼,例如:

struct MyData { 

    template <typename FUNC> 
    void run(FUNC func) { 
     for (auto& i : ints) { 
       func(i); 
     } 
     for (auto& f : floats) { 
       func(f); 
     } 
    } 

    std::vector<int> ints; 
    std::vector<floats> floats; 
}; 

,然後使用類似於

MyData myData = /**/; 

myData.run([](auto e){ std::cout << e << " "; });