Probleme mit templates und Container



  • Hi,

    ist sowas nicht möglich?

    template <typename container>
    void output ( container<std::string> &i ){
    	std::ostream_iterator<var> write ( std::cout, " " );
    	std::copy ( i.begin(), i.end(), write );
    }
    

    Ausgabe:

    1>.\Main.cpp(402) : error C2143: Syntaxfehler: Es fehlt ')' vor '<'
    1>.\Main.cpp(402) : error C2143: Syntaxfehler: Es fehlt ';' vor '<'
    1>.\Main.cpp(402) : error C2988: Unerkannte Vorlagendeklaration/-definition
    

    Kann ich also kein Template für einen Container (vector, deque...) erstellen?



  • Dafür gibt es template-template-Parameter

    template<template<typename T> class Container>
    void foo(Container<int> const &c);
    


  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Rund um die Programmierung in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Wenn ich jetzt nur die Funktion im Quellcode stehen habe

    template<template<typename T> class container>
    void output ( container<std::string> &i ){
    	std::ostream_iterator<std::string> write ( std::cout, " " );
    	std::copy ( i.begin(), i.end(), write );
    }
    

    dann bekomme ich keine Fehler.
    Aber sobald ich schreibe

    std::vector<std::string> str1;
    str1.push_back ( "bla" );
    str1.push_back ( "blabla" );
    output ( str1 );
    

    bekomme ich den Fehler

    1>.\Main.cpp(419) : error C2784: "void output(container<std::string> &)": template-Argument für "container<std::string> &" konnte nicht von "std::vector<_Ty>" hergeleitet werden.
    1>        with
    1>        [
    1>            _Ty=std::string
    1>        ]
    1>        .\Main.cpp(402): Siehe Deklaration von 'output'
    

    Hab ich da was falsch verstanden?



  • Die meisten STL-Container (wenn nicht sogar alle) bieten das typedef "value_type" an:

    template<class Container>
    void output ( const Container& i )
    {
        std::ostream_iterator<Container::value_type> write( std::cout, " " );
    	std::copy ( i.begin(), i.end(), write );
    }
    

    edit: Ich würde aber statt dieser Funktion eher den operator<< überladen:

    template<typename T>
    std::ostream& operator<<( std::ostream& out, const std::vector<T>& c )
    {
    	std::ostream_iterator<T> write( out, " " );
    	out << "[ ";
    	std::copy( c.begin(), c.end(), write );
    	return out << "]";
    }
    


  • Badestrand schrieb:

    template<class Container>
    void output ( const Container& i )
    {
        std::ostream_iterator<Container::value_type> write( std::cout, " " );
    	std::copy ( i.begin(), i.end(), write );
    }
    

    Danke, das funktioniert perfekt.

    Badestrand schrieb:

    edit: Ich würde aber statt dieser Funktion eher den operator<< überladen:

    template<typename T>
    std::ostream& operator<<( std::ostream& out, const std::vector<T>& c )
    {
    	std::ostream_iterator<T> write( out, " " );
    	out << "[ ";
    	std::copy( c.begin(), c.end(), write );
    	return out << "]";
    }
    

    Das mit dem überladen von Operatoren, muss ich mir erst mal genau ansehen. Davon habe ich bis jetzt noch keine Ahnung.

    Jedenfalls danke für die Anworten


  • Administrator

    EEK@work schrieb:

    Wenn ich jetzt nur die Funktion im Quellcode stehen habe

    template<template<typename T> class container>
    void output ( container<std::string> &i ){
    	std::ostream_iterator<std::string> write ( std::cout, " " );
    	std::copy ( i.begin(), i.end(), write );
    }
    

    ...

    // ... std::vector übergabe ...
    

    Hab ich da was falsch verstanden?

    Um noch auf diese Frage eine Antwort zu geben. Ja du hast einen Fehler gemacht. Die Standardbibliothek Container haben meistens zwei Templateparameter. Soweit mir bekannt ist, dürften sie sogar mehr als zwei haben, aber meistens haben sie nur zwei. Daher müsste der Code so lauten:

    // template<typename, typename> <- zwei typenames
    template<template<typename, typename> class container>
    void output ( container<std::string, std::allocator<std::string> > &i )
    {
    	std::ostream_iterator<std::string> write ( std::cout, " " );
    	std::copy ( i.begin(), i.end(), write );
    }
    

    Dies allerdings nur zur Vollständigkeit. Ich rate eher zur Lösung von Badestrand. Template-Template-Parameter sind immer ein wenig mühsam und unflexibel.

    Grüssli



  • Dravere schrieb:

    Dies allerdings nur zur Vollständigkeit. Ich rate eher zur Lösung von Badestrand. Template-Template-Parameter sind immer ein wenig mühsam und unflexibel.

    Sie sind häufig flexibel genug - wenns sich nicht gerade um STL-Container handelt 😉

    EEK@work schrieb:

    Das mit dem überladen von Operatoren, muss ich mir erst mal genau ansehen. Davon habe ich bis jetzt noch keine Ahnung.

    Da gibts n Artikel im Magazin zu 😉 Wenn du Funktionsüberladungen kennst sollte dir das damit keine großen Probleme bereiten...


  • Administrator

    pumuckl schrieb:

    Sie sind häufig flexibel genug - wenns sich nicht gerade um STL-Container handelt 😉

    Template-Template-Parameter habe ich bisher immer nur als Einschränkung angesehen. Gut, man muss vielleicht etwas weniger schreiben, aber ansonsten ist es eine Einschränkung des zu übergebenen Typs. Sowas würde ich nicht unbedingt als flexibel bezeichnen 😉

    pumuckl schrieb:

    EEK@work schrieb:

    Das mit dem überladen von Operatoren, muss ich mir erst mal genau ansehen. Davon habe ich bis jetzt noch keine Ahnung.

    Da gibts n Artikel im Magazin zu 😉 Wenn du Funktionsüberladungen kennst sollte dir das damit keine großen Probleme bereiten...

    LoL, das scheint der wichtigste Artikel überhaupt zu werden, oder du machst einfach zu viel Eigenwerbung 😃

    Grüssli



  • Dravere schrieb:

    pumuckl schrieb:

    Sie sind häufig flexibel genug - wenns sich nicht gerade um STL-Container handelt 😉

    Template-Template-Parameter habe ich bisher immer nur als Einschränkung angesehen. Gut, man muss vielleicht etwas weniger schreiben, aber ansonsten ist es eine Einschränkung des zu übergebenen Typs. Sowas würde ich nicht unbedingt als flexibel bezeichnen 😉

    Nicht so flexibel wie allgemeine templateparameter, das mag sein. Aber in vielen Fällen eben doch flexibel genug.

    pumuckl schrieb:

    LoL, das scheint der wichtigste Artikel überhaupt zu werden, oder du machst einfach zu viel Eigenwerbung 😃

    Andersrum - ich hab den Artikel geschrieben weils ein ständig wiederkehrendes Thema ist - und ja, ich mache Eigenwerbung 😉


Anmelden zum Antworten