Nehmen wir an, ich habe einen C-Container (z. B. MyContainer
) mit enthaltenen Objekten, die als void*
-Zeiger gespeichert sind. Die einzige Möglichkeit, die Elemente dieses Containers zu durchlaufen, sind zwei Interface-Funktionen:
getFirstElem(MyContainer const&, void*)
: Gibt das erste Element des Containers aus. getNextElem(MyContainer const&, void*)
: Gibt das nächste Element des Containers aus. Ich möchte eine generische Funktion codieren, die die Elemente dieses C-Containers über die oben genannten Schnittstellenfunktionen iteriert und ihre Werte in einen C ++ - Container kopiert (z. B. std::vector
).
Was ich bisher gemacht habe:
%Vor% Das obige Beispiel funktioniert mit normalen Iteratoren. Es kann jedoch nicht mit Ausgabe-Iteratoren kompiliert werden (z. B. copy_container(cont, std::back_inserter(myvector));
).
Der Grund ist, dass std::iterator_traits::value_type
in void
resultiert, wenn der Argumenttyp ein Ausgabe-Iterator ist.
Gibt es eine Möglichkeit, diese generische Funktion auch für Ausgabe-Iteratoren zu verwenden?
Ich weiß, dass es in C ++ 11 mit decltype
möglich war (zB decltype(*first)
), aber ich bin besonders an Pre-C ++ 11-Lösungen interessiert, da ich einen alten C ++ - Compiler verwende ( gcc v4.4.7).
Wie richtig beobachtet, ist value_type
eines Ausgabe-Iterators void
. Es gibt also nicht viel zu tun, außer das zu ersetzen:
mit diesem
%Vor%(obwohl der Standard nicht garantiert, wird es funktionieren - ein Proxy könnte zurückgegeben werden, indem ein Ausgabe-Iterator deaktiviert wird).
Da Sie keine C ++ 11-Lösung angegeben haben, ist möglicherweise ein Redesign erforderlich. Hier sind einige Optionen:
Anstelle eines Iterators für das erste Element könnten Sie einen Verweis auf den Container übergeben. Es scheint, als ob alles, was Sie wollen, ist ein Push_back
%Vor%Dann brauchen Sie nur eine Ebene von Merkmalen, die Sie zur richtigen Implementierung der Einfügung pro Container senden können
Der Werttyp könnte ein zusätzlicher Vorlagenparameter sein
%Vor%Es gibt verschiedene Wege das zu lösen, ich habe es so gemacht:
%Vor%Ich habe einen anderen für den üblichen Iterator.