You don't need to make your friend
a template:
friend std::ostream& operator<<(std::ostream& os, const Derived& dt);
This needs to be changed to:
friend std::ostream& operator<< <>(std::ostream& os, const Derived& dt);
The operator<<
function will need to be visible before the friend
declaration for this form to work.
You should prefer this form to making the friend
a template because you don't need all of the operator's instantiations to be friend
s, just one of them.