I saw many implementation of type-safe printf, but most of them are using exception to raise type errors.
As exercise, I implemented prototype of printf-like formatting using string literals, and it seems to solve all the problems with old, good printf family (except using format read from external source which is always not safe).
Example:
int main(int argc, char* argv[])
{
std::cout << "const char*: %s, std::string: %s\n"_format("ONE", std::string{"TWO"});
std::cout << "user defined: %*\n"_format(std::complex<int>{1, 2});
std::cout << "hex: 0x%x, int: %d\n"_format(16, 123);
std::cout << "double.2: %.2f, double: %f\n"_format(13.123123, 12.1);
std::string s = "p(%d, %d)\n"_format(123, 234);
std::cout << s;
// not yet working
// int x, y;
// std::cin >> "p(%d, %d)"_format(x, y);
// "p(%d, %d)"_format(x, y) = "p(999, 888)";
}
Full, dirty and not complete nor optimized code is here
Generated .s
shows that no text processing is done in runtime, even if variables are not const
, but taken for example from argv
. Passing wrong variable type, or using argument count cause ugly compilation error, which could be improved with static asserts or concepts.
This is only exercise, and the question is: Is it any library, which supports such constructions, and why such approach is not part of c++ standard?
The {fmt} library and C++20 std::format
have compile-time format string checks. For example (https://godbolt.org/z/vr57bqzb3):
#include <fmt/core.h>
int main() {
std::string s = fmt::format("{:d}", "I am not a number");
}
gives a compile-time error because d
is an invalid format specifier for a string. This uses Python-like format string syntax, not printf syntax though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With