The introduction of std::format
into C++20 is very nice and can even be used (from fmtlib
itself) in iterations before C++20. It certainly allows for less verbose code than the iostream
equivalent code that came before it.
Contrast, for example, the following two statements where the latter seems clearer and more succinct (to me, anyway):
std::cout << "Your name is " << name << " and your licence number is "
<< std::setw(9) << std:setfill('0') << num << ".\n";
fmt::print("Your name is {} and your licence number is {:09}.\n", name, num);
However, the iostream
method still has one small advantage in that the things that are to be printed are in the sequence in which they're listed, so you can read them from left to right. Well, provided you can ignore all the "noise" in the statement (<<
, setw
, and the like) :-)
In other words, you don't really have to look (too far) ahead to the arguments to see what's being printed.
In that sense, std::format
is more like Python's str.format()
(and C's printf
) method as they both list a format string with special markers (like {}
or %09d
), followed by arguments which are slotted in to where those markers are.
I was wondering whether it would be possible to use C++'s recent meta-programming features to provide true f-strings, something like Python's:
print("Your name is {name} and your licence number is {licence_num:09}.\n");
This inlining of the expressions to output would be much easier to read in the code. I know rather little of the code generation capabilities of C++20, so I wonder if it's plausible to take a statement like that above and generate a new statement in the "accepted" form.
This would be done as part of the compilation process itself (not some pre-processing tool that likely introduces extra opportunity for problems). That way, you would never actually see the modified line, it would just magically be made from the more readable form, compiled, and thrown away.
In other words, an expression such as:
magic::fstring("Your name is {name} and your licence number is {num:09}.\n");
would become this for compilation:
fmt::format("Your name is {} and your licence number is {:09}.\n", name, num);
I've read the Sutton and Childers P1717R0 "Compile-time Metaprogramming in C++" document and tried to do some other research, but I'm not entirely sure that the consteval
and meta
things provide enough power to break apart a string like that above at compile time.
Can anyone more knowledgeable about these features in C++20 indicate whether this would be a viable approach and, if so, how it would be done?
Or, alternatively, there may be another way of doing this, I'd be grateful for any suggestions on that front.
That syntax is not possible without a change to the language itself, but how about something like this: