我看到很多类型安全的printf实现,但是大多数都使用异常来引发类型错误。
作为练习,我使用字符串文字实现了类似printf的格式化原型,它似乎解决了旧的,良好的printf系列的所有问题(除了使用从外部源读取的格式,这总是不安全)。
示例:
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)";
}
完整,肮脏且不完整或优化的代码为here
生成的.s
表示在运行时没有进行文本处理,即使变量不是const
,而是从argv
获取。传递错误的变量类型,或使用参数计数会导致丑陋的编译错误,这可以通过静态断言或概念进行改进。
这只是练习,问题是:是否有支持此类构造的库,以及为什么这种方法不是c ++标准的一部分?
答案 0 :(得分:2)
有没有这样的图片?排序:GCC(和其他编译器)理解printf
格式字符串的语法,如果类型不匹配,可以说服它发出编译时错误。
为什么这种方法不属于C ++?因为Bjarne最初提出了iostream,它也提供类型安全的IO,没有人对此有足够的感觉来提出另一个提案。
答案 1 :(得分:0)
{fmt} library具有编译时格式字符串检查。例如
#include <fmt/format.h>
int main() {
std::string s = fmt::format(FMT_STRING("{:d}"), "hello");
}
给出了编译时错误,因为d
是字符串的无效格式说明符。这使用类似Python的格式字符串语法,但不使用printf语法。