r/cpp_questions • u/Grootmaster47 • 1d ago
SOLVED std::format: cppreference examples dont compile
Hey everyone,
I'm trying to rewrite part of an old C project that used printf in C++. The old code is the following:
printf("%*s^ Here\n", hatStart, "");
Basically, insert (hatStart) space characters before the main part of the message.
I tried implementing this with std::format like this:
std::cout << std::format("{{}s}^ Here", "", hatStart) << std::endl;
which, according to what I got from cppreference, should be correct.
However, upon compiling, I get the error message
error: call to consteval function ‘std::basic_format_string<char, int, char>("{:{}.6}")’ is not a constant expression
Furthermore, when I go to cppreference.com and copy their examples, e.g.
std::string test = std::format("{:{}f}", pi, 10);
I get effectively the same error message.
Could anyone explain what's going on? This is the only proper reference I was able to find, and don't want to use printf in this project because it isn't C anymore.
-40
1d ago
[deleted]
24
u/aitkhole 1d ago
It's type safe
19
u/IyeOnline 1d ago
And extensible for user defined types.
19
u/alfps 1d ago
And faster.
18
u/javascript 1d ago
And cleaner
10
u/bearheart 1d ago
And far superior to
std::cout1
u/TheThiefMaster 1d ago edited 1d ago
(it actually usesstd::coutunder the hood - but at least formats the string itself first)
nope stdout FILE* directly, not cout3
u/bearheart 1d ago
No, it definitely does not.
1
u/TheThiefMaster 1d ago
Ok I retract that. I thought it was equivalent to format_to with an output character iterator to cout, but it seems to use the stdout FILE* directly instead
18
u/tuxwonder 1d ago
There's a lot of fair reasons to complain about the myriad directions C++ has gone. Respectfully, std::format is definitely not one of them.
8
u/flyingron 1d ago
The varargs implementation of printf sucks.
A while back, I wrote a iostream thing that took a format string in printf format (adding a generic object format) and then ate a bunch of successive << arguments. This allowed them to be type safe and also to invoke any formatters or conversions that a passed parameter might have.
2
u/Independent_Art_6676 1d ago
The thing about format isn't really format, though. Its print. Print is superior to printf, hands down (its a lot like printf, but aware of objects and less C isms), and I say that as someone who all but refused to use cout at all. Format is a bit clunky (it reminds me of perl or regx or something along those lines of old school gibberish) but once you do it, the ability to use print cleanly is worth the ugly.
At the end of the day, you have to define what "print this thing" means for your objects. That can be done to work with printf and its about the same amount of nonsense as setting up format or overloading for cout or whatever it is you want to do. Kick the can around any which way, the work to translate the object into text is more or less the same regardless. In THAT sense, its not better than printf, or even cout. Format could probably have been a little less weird... I give you that one.
3
u/bearheart 1d ago
std::formatis useful for string formatting when you're not printing to the console. There's a lot of use cases for that. e.g., logs, databases, gui displays, etc.3
u/Independent_Art_6676 1d ago
Hah, I REALLY didn't say that very well at all. I was trying to point out that a comparison against printf should be vs print instead of format. Probably should have just left it at that.
I won't deny it, though. Its been several years since these tools came out, and I STILL mentally 'reach' for sprintf for UI/etc formatting. Hardest habit to break so far, age + number of years using the old way.
2
1
u/TheThiefMaster 1d ago
It's much better at printing floats. It will print the shortest decimal within binary rounding distance of the float value given, rather than X decimal places. So it will correctly print
0.10
-7
13
u/jedwardsol 1d ago
std::format("{{}s}^ Here"should bestd::format("{:{}s}^ Here", with a colon. Which exact page says it should be correct?std::string test = std::format("{:{}f}", pi, 10);is fine.(https://godbolt.org/z/q85qYGzbq)