Explizite Typangaben bei Tempalte-Ausgabeoperator



  • #include <iostream>
    
    template<typename T> class Printable;
    
    template<typename T>
    std::ostream& operator<<(std::ostream& out, const Printable<T>& p)
    {
    	out << p.value;
    	return out;
    }
    
    template<typename T>
    class Printable
    {
    	friend std::ostream& operator<< <T>(std::ostream&, const Printable<T>&);
    
    	public:
    	Printable(T val): value(val) {}
    
    	private:
    	T value;
    };
    
    int main()
    {
    	Printable<int> pi(3);
    
    	operator<<(std::cout, pi); // funktioniert
    	operator<< <int>(std::cout, pi); // funktioniert nicht
    
    	return 0;
    }
    

    Kann mir jemand erklären, wieso der implizite Aufruf klappt, der explizite aber nicht? Der gleiche Code funktioniert, wenn icih operator<< durch eine normale Template-Funktion "print" ersetze.


  • Administrator

    Klammern setzen:

    (operator<< <int>)(std::cout, pi);
    

    Ich muss aber eingestehen, dass ich zu der späten Stunde nicht mehr einen genug klaren Kopf habe, dass ich dir sagen kann, wieso. Weiss nur noch, dass die Klammern nötig waren ...

    Grüssli



  • Ja, funktioniert tatsächlich! Das warum wäre jetzt natürlich noch sehr interessant.



  • Rätsler schrieb:

    Ja, funktioniert tatsächlich! Das warum wäre jetzt natürlich noch sehr interessant.

    Zu alter Compiler? Was hat du den für einen?
    Bei VC++08 funktioniert das ganze Wunderbar..

    Zu dem warum. Ich denke mal, dass es da Probleme mit dem Parsen gibt/gab. Mittlerweile sollte das aber auch in Ordnung sein.



  • Bei meinem VC++08 funktioniert das ganze nicht!


  • Administrator

    Finde leider die Quelle nicht mehr, woher ich das habe und kann daher auch nur noch Mutmassungen anstellen.
    g++ kompiliert es jedenfalls ohne Probleme und meiner Meinung nach, sollte ein standardkonformer Kompiler sowas auch ohne Probleme kompilieren.

    Der MSVC könnte womöglich Probleme damit haben, weil es keine "normale" Funktion ist, was den Namen betrifft. Es hat Abstände und Sonderzeichen darin, wodurch die Sache nicht auf Anhieb als Funktion erkannt wird. Durch die zusätzliche Klammerung kann man dem Kompiler wohl helfen.
    Aber das ist eine reine Vermutung ...

    Grüssli


Anmelden zum Antworten