We have println at home
While working through Crafting Interpreters in C++, I wanted to explore as many modern C++ features as I could.
One of the features I was the most hyped for was print and println.
Finally, a normal way to print things! I provided std::formatter specializations for my TokenType and Token classes, and in my main.cpp I excitedly typed:
std::printlnonly for my IDE to not provide an autocompletion that would include the header file.
Indeed, I did not have the <print> header on my machine.
I figured my C++ toolchain was too old and didn’t have support for it yet. “Ah, no problem,” I thought, “this is what I have mise for.” But trying to install a newer clang with mise resulted in mise trying to compile it from source, which I didn’t want to sit around and wait for.
So I glumly stuck with using std::cout and std::format as per this StackOverflow answer.
std::cout << std::format("{}", token) << std::endl;But this left me feeling unsatisfied. It was so verbose.
Maybe I could just implement print and println myself.
I copied the signatures of print and println from cppreference
and implemented them like so:
#include <format>#include <iostream>#include <iterator>
template<class... Args>void print(std::format_string<Args...> fmt, Args &&... args) { static std::ostream_iterator<char> out(std::cout); std::format_to(out, fmt, args...);}
template<class... Args>void println(std::format_string<Args...> fmt, Args &&... args) { print(fmt, args...); std::cout << std::endl;}- Based on this other StackOverflow answer.
- Flush
couton every new line, just like Java’s System.out.println.
This worked! In my main.cpp, I could now do
println("{}", token);My implementation is far less complete than LLVM’s, but it does the job for my simple tree walk interpreter, and I’m happy with it.