T
Hallo Stefan,
wenn Du Impl public machst, gibst Du keine Informationen raus, da Du Impl weiterhin einfach in .cpp definieren kannst. Ich finde es eigentlich ungewöhnlich operator<< immer als friend zu deklarieren. Einfach ein forwarding an eine öffentliche Funktion ergibt die gewünschte Syntax:
class A
{
public:
struct Impl;
private:
std::unique_ptr<Impl> pImpl;
};
std::ostream& operator<<( std::ostream&, const A& );
.cpp
class A::Impl
{
public:
void print( std::ostream& ) const;
};
std::ostream& operator<<( std::ostream& out, const A& a )
{
a.print( out );
return out;
}
Wenn operator<<() aber unbedingt ein template sein muss, dann kommst Du wohl nicht darum herum, Impl im header zu definieren. Es sei den, die Liste der Instanziierungen ist übersichtlich, bekannt und klein; dann könntest Du das template auch in .cpp definieren und explizit instanzieren.
Kleiner Hinweis noch: Bezeichner, die mit einem _ anfangen, gefolgt von einem Großbuchstaben, sind für die Implementierung reserviert. Du dürftest Dich also nicht beschweren, wenn irgend eine Standardlibrary _OStream als Makro definiert.
mfg Torsten