Typ auf den Template-Iterator zeigt rauskriegen



  • 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.





  • ä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 zu

    read_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 compiled

    die 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.


Anmelden zum Antworten