2016-12-26 7 views
1

Mit Hilfe einer Vorlage überlastet ich Operator < <, so dass es alle Elemente eines Containers ausgibt:Die überladene Operator << Vorlage funktioniert nicht für std :: list, obwohl es für std :: vector

template<typename T, template<typename> typename C> 
ostream& operator<<(ostream& o, const C<T>& con) { for (const T& e : con) o << e; return o; } 

es funktioniert OK mit std::vector s, aber es erzeugt eine Fehlermeldung, wenn ich es auf einen std::list anzuwenden versuchen:

error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream}’ and ‘std::__cxx11::list’) cout << li;

Hier ist mein Codeauszug ist (auf GCC kompiliert 5.2.1, Ubuntu 15.10):

#include "../Qualquer/std_lib_facilities.h" 

struct Item { 

    string name; 
    int id; 
    double value; 

    Item(){}; 
    Item(string n, int i, double v): 
     name{n}, id{i}, value{v} {} 
}; 

istream& operator>>(istream& is, Item& i) { return is >> i.name >> i.id >> i.value; } 
ostream& operator<<(ostream& o, const Item& it) { return o << it.name << '\t' << it.id << '\t' << it.value << '\n'; } 

template<typename T, template<typename> typename C> 
ostream& operator<<(ostream& o, const C<T>& con) { for (const T& e : con) o << e; return o; } 


int main() 
{ 
    ifstream inp {"../Qualquer/items.txt"}; 
    if(!inp) error("No connection to the items.txt file\n"); 

    istream_iterator<Item> ii {inp}; 
    istream_iterator<Item> end; 
    vector<Item>vi {ii, end}; 
    //cout << vi;//this works OK 
    list<Item>li {ii, end}; 
    cout << li;//this causes the error 
} 

Allerdings, wenn ich eine Vorlage speziell für die std::list schreiben, es funktioniert OK:

template<typename T> 
ostream& operator<<(ostream& o, const list<T>& con) { for (auto first = con.begin(); first != con.end(); ++first) o << *first; return o; } 

Warum die ostream& operator<<(ostream& o, const C<T>& con) Vorlage für nicht anwendbar zu sein, erweist sich std::list?

+3

soweit ich Ihre Template Operator nimmt Container sehen, dass nur ein Template-Parameter 'Vorlage Typname C' als solche sowohl' std :: nimmt vector 'und' std :: list' sollten nicht übereinstimmen –

+1

Das ist Bjarnes Lehrkopf, richtig? Er hat eine 'Vorlage Klasse Vector' und einen' #define Vektor Vector'. @ W.F. –

+0

@ T.C. Ja, die Header-Datei ist Bjarnes Lehrkopf von seiner Site. – Jarisleif

Antwort

2
template<typename T, template<typename> typename C> 
ostream& operator<<(ostream& o, const C<T>& con) { for (const T& e : con) o << e; return o; } 

Warum so kompliziert? Sie benötigen den Namen T nur, um es in Ihrer for-Schleife zu verwenden. Sie können es durch C::value_type bekommen auch oder gerade auto Schlüsselwort:

template<typename C> 
ostream& operator<<(ostream& o, const C& con) 
{ 
    for (const typename C::value_type& e : con) o << e; return o; 
} 

template<typename C> 
ostream& operator<<(ostream& o, const C& con) 
{ 
    for (auto& e : con) o << e; return o; 
} 
Verwandte Themen