I came up with this, basically overriding std::endl using the custom my_endl shell, accepting the default template options. Not the most elegant, but he does his job. Of course, for more of these manipulators you need to write a special shell, but I think that even this can be somehow possible with the help of a smarter implementation.
#include <iostream> #include <string> #include <type_traits> class Logger { public: template<typename T> void log(T val); template <typename T, typename ...Args> void log(T val, Args... args); }; template<typename T> void Logger::log(T val) { std::cout << val; } template<typename T, typename ...Args> void Logger::log(T val, Args... args) { log(val); log(args...); } template< class CharT = char, class Traits = std::char_traits<CharT> > inline std::basic_ostream<CharT, Traits>& my_endl( std::basic_ostream<CharT, Traits>& os ) { return std::endl(os); } // or, use the excellent (and better) suggestion by 0x499..., // auto manip = std::endl<char, std::char_traits<char>>; // log.log(..., manip) int main(int argc, char* argv[]) { Logger log; // log.log("Nazdar ", "bazar ", "cau", std::endl, "kik"); // ERROR: cannot determine which instance of function template "std::endl" is intended log.log("Nazdar ", "bazar ", "cau", my_endl<>, "kik"); std::cin.get(); return 0; }
source share