https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107813
--- Comment #3 from Grzegorz Drzewiecki <gdrzewo at gmail dot com> --- (In reply to Jonathan Wakely from comment #1) > When you call this->o << t then there is no exact match, so an implicit > conversion to unsigned char happens. OK. But what botter me. I've added global operator like: std::ostream &operator<<(std::ostream &os, unsigned char c) { return os << static_cast<unsigned int>(c); } With this one my example works fine: f << cat << " vs " << dog << "\n\r"; stdout: 67 vs 68. There is different conversion for either global operator or template operator.