2011-06-19 50 views
6

我想更好地保持迭代器和泛型函數。我認爲編寫一個將container1 < container2 <type> >轉換爲container3 <type>的函數將是一個有用的練習。例如,它應該能夠將vector< deque<int> >轉換爲list<int>通用函數來扁平一個容器的容器

我想所有的容器訪問都應該通過迭代器,就像<algorithm>中的函數一樣。

這裏是我的代碼:

#include <iterator> 
#include <algorithm> 

// COCiter == Container of Containers Iterator 
// Oiter == Output Iterator 
template <class COCiter, class Oiter> 
void flatten (COCiter start, COCiter end, Oiter dest) 
{ 
    using namespace std; 

    while (start != end) { 
     dest = copy(start->begin(), start()->end(), dest); 
     ++start; 
    } 
} 

但是當我嘗試調用它在下面的代碼:

int main() 
{ 
    using namespace std; 

    vector< vector<string> > splitlines; 
    vector<string> flat; 

    /* some code to fill SPLITLINES with vectors of strings */ 

    flatten(splitlines.begin(), splitlines.end(), back_inserter(flat)); 
} 

我得到一個巨大的C++模板的錯誤消息,undefined reference to void flatten< ... pages of templates ...

我感覺就像我的代碼太容易編寫了,並且我必須需要更多的東西來確保內部容器中的數據類型與輸出容器中的數據類型匹配。但我不知道該怎麼做。

+0

請注意,堆棧沒有迭代器,也沒有開始/結束函數。如果你想要它與棧一起工作,你肯定會特殊情況下它。 –

+0

這是真的;我會改變這個問題。我實際上並不需要堆疊兼容性;只是可迭代的容器。 – japreiss

回答

8

我發現了這個問題。由於SFINAE(替換失敗不是錯誤),您的編譯器無法找到正確的模板,因爲您正嘗試通過輸入start()(可能是拼寫錯誤)致電operator()start。試試這個:

#include <iterator> 
#include <algorithm> 

// COCiter == Container of Containers Iterator 
// Oiter == Output Iterator 
template <class COCiter, class Oiter> 
void flatten (COCiter start, COCiter end, Oiter dest) { 
    while (start != end) { 
     dest = std::copy(start->begin(), start->end(), dest); 
     ++start; 
    } 
} 
+0

SFINAE不適用於在函數體內發生的替換失敗。它只適用於函數簽名(返回類型和參數)。 –

+0

但是,您的修復程序工作:) –

+0

這確實是一個錯字,但事實證明,我也在將包含通用函數原型的錯誤包含在頭文件中。我發現你不能那樣做;你必須包含整個cpp文件(我認爲)。 – japreiss

相關問題