2011-06-19 12 views
6

Próbuję lepiej uchwycić iteratory i ogólne funkcje. Pomyślałem, że byłoby pożytecznym ćwiczeniem napisać funkcję, która konwertuje container1 < container2 <type> > na container3 <type>. Na przykład powinna być w stanie przekonwertować vector< deque<int> > na list<int>.Ogólna funkcja spłaszczania kontenera kontenerów

Doszedłem do wniosku, że cały dostęp do kontenera powinien odbywać się za pomocą iteratorów, takich jak funkcje w <algorithm>.

Oto mój kod:

#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; 
    } 
} 

Ale gdy próbuję to nazwać w poniższym kodzie:

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)); 
} 

dostaję ogromną C komunikat o błędzie szablon ++, undefined reference to void flatten< ... pages of templates ...

I Czuję, że mój kod jest zbyt łatwy do napisania i potrzebuję trochę więcej rzeczy, aby upewnić się, że typ danych w wewnętrznych kontenerach jest zgodny z typem danych w kontenerze wyjściowym. Ale nie wiem, co robić.

+0

Zauważ, że stos nie ma iteratorów i nie ma funkcji początku/końca. Jeśli chcesz, aby pracował ze stosami, z pewnością będziesz musiał to zrobić w specjalnym przypadku. –

+0

To prawda; Zmienię pytanie. Tak naprawdę nie potrzebuję kompatybilności stosu; tylko pojemniki z możliwością iteracji. – japreiss

Odpowiedz

8

Znalazłem problem. Dzięki SFINAE (błąd zastąpienia nie jest błędem) kompilator nie może znaleźć poprawnego szablonu, ponieważ próbujesz wywołać operator() na start, wpisując start() (prawdopodobnie literówka). Wypróbuj to:

#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 nie działa dla niepowodzeń substytucji, które wystąpiłyby w ciele funkcji. Działa tylko w sygnaturze funkcji (typ i parametry zwracane). –

+0

Jednak twoja poprawka działa :) –

+0

To był rzeczywiście literówka, ale okazało się, że popełniłem błąd włączenia prototypu funkcji ogólnej do pliku nagłówkowego. Właśnie się dowiedziałem, że nie możesz tego zrobić; musisz uwzględnić cały plik cpp (chyba). – japreiss

Powiązane problemy