friend std::ostream& operator<<(std::ostream& os, const Derived& dt);
declares a non template version friend
, so you would have to implement
std::ostream& operator<<(std::ostream& os, const Derived& dt);
for every T
you use:
std::ostream& operator<<(std::ostream& os, const Derived& dt) {
return os << dt.data_;
}
And so on.
A way to do it without duplicate code is with definition inside the class:
template
class Derived : public IBase
{
public:
explicit Derived(T data);
friend std::ostream& operator<<(std::ostream& os, const Derived& dt)
{
return os << dt.data_;
}
private:
T data_;
};
Demo
An other alternative is to make the function template.
// Forward declarations
template class Derived;
template std::ostream& operator<<(std::ostream& os, const Derived& dt);
And then in Derived
, you have 2 choices:
Declare each the template method friend:
template
friend std::ostream& operator<<(std::ostream& os, const Derived& dt);
So std::ostream& operator<<(std::ostream& os, const Derived& dt)
has access to private members of Derived
, but also to the ones of Derived
Demo
Declare only the template which matches the argument:
friend std::ostream& operator<< <>(std::ostream& os, const Derived& dt);
and so std::ostream& operator<<(std::ostream& os, const Derived& dt)
doesn't have access to private members of Derived
.
Demo