我看到过许多类型安全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
中获取的示例。传递错误的变量类型或使用参数计数会导致严重的编译错误,可以使用静态Assert或概念来改善这种错误。
这只是演习,问题是:是否有任何库支持这样的构造?为什么这样的方法不是c++标准的一部分?
3条答案
按热度按时间bakd9h0s1#
{fmt} library和C++20
std::format
具有编译时格式字符串检查。例如(https://godbolt.org/z/vr57bqzb3):给出一个编译时错误,因为
d
是一个无效的字符串格式说明符。这使用了类似Python的格式字符串语法,而不是printf语法。aij0ehis2#
有这样的图书馆吗?GCC(和其他编译器)理解
printf
字符串的语法,如果类型不匹配,可以被说服发出编译时错误。为什么这种方法不是C++的一部分?因为Bjarne最初提出了iostream,它也可以实现类型安全IO,没有人对此有足够的强烈感受,从而提出了替代建议。
zengzsys3#
使用 variadic templates,您可以简单地拥有printf的自定义类型安全版本:
检查一下:
输出量: