Typ auf den Template-Iterator zeigt rauskriegen
-
Hmm, das scheint es noch nicht ganz zu sein - es hagelt noch Fehler, aber Danke trotzdem.
Aber wir nähern uns der Sache glaube ich an.
Ich compiliere übrigens mit dem MSVC++6, vielleicht frisst der ja auch nicht alles?
wer kann weiterhelfen?
-
scrontch schrieb:
Hmm, das scheint es noch nicht ganz zu sein - es hagelt noch Fehler
zeig mal die ersten beiden.
-
d:\programme\microsoft visual studio\vc98\include\utility(81) : error
039: 'iterator_category' : is not a member of '`global namespace''
d:\home\projects\tools\include\csvio.h(47) : see reference to class template instantiation 'std::iterator_traits<int *>' being compiled
D:\Home\Projects\Tools\TestIo\test.cpp(81) : see reference to function template instantiation 'void __cdecl read_csv(class std::basic_istream<char,struct std::char_traits<char> > &,int *,int)'die erste Zeile bezieht sich auf ein MSVC-file:
// TEMPLATE CLASS iterator_traits (from <iterator>) template<class _It> struct iterator_traits { typedef _It::iterator_category iterator_category; // <-- Fehler! typedef _It::value_type value_type; typedef _It::distance_type distance_type; };
die zweite auf das Besprochene
typename std::iterator_traits<output_iterator_t>::value_type value;
die dritte auf den Funktionsaufruf
read_csv(input, v.begin(), 4);
dabei ist v deklariert wie im Beispiel: vector<int> v;
-
Hm, versucht der VC6, T*::iterator_category zu ermitteln (daher der globale Namespace), weil er die partielle Spezialisierung für T* nicht peilt? Zumindest in meiner MSDN stehen unter "iterator_traits" noch ein paar Workarounds ohne partielle Spezialisierung, vielleicht findest du da bei dir ja auch was...
-
Nun, der VC6 unterstützt in der Tat keine partiellen Template-Spezialisierungen
Könnt ihr mir erklären wo das Problem hier genau auftritt?
Ich werde dann heut Abend mal die Workarounds ausprobieren. (bin auf Arbeit)
Danke.
-
@scrontch
Schon gelesen?http://www.c-plusplus.net/forum/viewtopic.php?t=36810&highlight=iteratortraits
-
äh... nein.
Danke! Ist ja genau mein Problem.
-
Hallo.
Ich habe nun das Problem wie im obigen Link beschrieben umgangen.
Die Sache läuft für vectors von ausreichender Grösse.
(Die Funktion iteriert darüber und ersetzt Inhalte)
Nun würde ich aber gern auch mit einem leeren vector anfangen können, d.h. ich habe den Aufruf geändert zuread_csv(input, back_inserter(v), 4);
Aber nun bekomme ich die Fehlermeldung
csvio.h(56) : error C2182: 'value' : illegal use of type 'void'
csvio.h(74) : see reference to function template instantiation 'void __cdecl _read_csv(class std::basic_istream<char,struct std::char_traits<char> > &,class std::back_insert_iterator<class std::vector<int,class std::allocator<int> > >,int,void *)' being compileddie entsprechenden Code-Schnipsel sind
template <typename output_iterator_t, typename value_t> void _read_csv(std::istream& is, output_iterator_t it, int n, value_t* dummy) { //... value_t value; //... } template <typename output_iterator_t> void read_csv(std::istream& is, output_iterator_t it, int n) { _read_csv(is, it, n, _Val_type(it)); }
Es scheint also so, dass _Val_type(it) = void* zurückliefert, was mir natürlich nicht recht ist.
was tun?
-
Seltsam.
typeid(back_insert_iterator<vector<int> >::value_type).name();
Gibt bei mir (VC7.1) auch "void" aus. std::back_insert_iterator ist von "_Outit" abgeleitet, das wiederum über Ableitung von std::iterator den value_type auf void setzt. Entspricht das dem Standard und hat das irgendeinen Sinn - ansonsten wäre es doch bestimmt schon geändert worden, wenn das offensichtlich seit fünf Jahren so ist? *wunder*
-
Hm, eine Runde Google Groups später glaube ich, dass es dem Standard entspricht, und scheinbar nicht nur für back_insert_iterator, sondern für alle nur schreibenden Iteratoren gilt (und die sind für deinen Algorithmus ja immerhin die halbe Zielgruppe), damit man ihnen beliebige Typen zuweisen kann. Ich würde entweder zwei Fliegen mit einer Klappe schlagen und den value_type als template-Parameter mit übergeben (dann nervt weder MSVC noch der Standard) oder deinen CSV-Reader als Input Iterator im Stile von istream_iterator umsetzen.
-
Ich hab da mal folgendes in VC++ 6.0 ausprobiert:
#include <vector> #include <iterator> template <typename T> void f(T &output) { T::value_type i = 34; output = i; } int main(int argc, char * argv[]) { std::vector<int> test; f(std::back_inserter(test)); return 0; }
das wird ohne Probleme kompiliert.
-
In VC7.1 geht das zumindest nicht mehr und es ist nicht standardkonform.