众所周知,如果由于某种原因你printf()
而不是流式传输(很少,但有时可能会发生),你需要指定一个合适的格式说明符(d
用于签名int,u
表示无符号等。现在,由于printf()
是C ++标准库的一部分而不仅仅是一些C遗留物,我希望可能会有类似
template <typename T>
const std::string format_specifier;
允许,说:
template <typename Foo>
void bar(const Foo& my_foo) {
printf(format_specifier<Foo>, my_foo);
}
标准库是否包含类似的内容?
备注:
std::cout
,当然这是您应该做的默认操作。我询问了标准库的一部分功能;如果它被删除了你可以说&#34;这绝不应该被使用,所以你的问题并不重要&#34;。答案 0 :(得分:3)
我最初把它写成评论,因为它看起来太短了。
简短的回答是“不”,因为C ++标准没有指定任何此类设施。
给出从C标准库继承的函数的属性,这是出于向后兼容的原因(没有重载,在全局命名空间和命名空间std中都允许等),以及使用C ++ iostream
类的方式是鼓励,如果这样的功能变得标准化,我会感到惊讶。
答案 1 :(得分:3)
由于某些原因,它在C ++库中不存在。
首先,如果您希望C ++帮助您找到输出对象的正确方法,C ++会为您提供stream
类的注入器。流选择适当的转换器,并且可以通过使用操纵器进行切换 - 甚至可以通过重载ostream& operator << (ostream&, const T&)
来指示如何打印任意对象。
但另一方面,printf格式字符串可以用于其他语言(Python,Java),对于使用它的旧程序员来说,比io操纵器更容易使用。但它可以用在相当复杂的字符串中,混合不同类型的常量标签和变量:
printf("Operation %-*s : %10.2f$ %2d%/02d\n", size, lib, val, dat->mday, dat->mon + 1);
我无法想象一种轻松构建该字符串的方法(并且它不使用 alternate 变体(#
))
因为它主要存在于兼容性的原因 - 毕竟几乎所有的C标准库都可以从C ++中使用 - 我无法想象它为什么需要进一步集成。
答案 2 :(得分:2)
没有,但你可以很容易地编码,例如:
template<typename T>
char const *format_specifier();
template<> inline char const *format_specifier<int>() { return "%d"; }
// ... in function
int d = 5;
printf(format_specifier<decltype(d)>, d);
这是相当粗略的恕我直言,仍然容易出错。可能是为什么它不在标准库中。
使用printf样式格式的更好的解决方案是代码:
my_printf("bla % bla % bla", arg1, arg2, arg3);
其中%
只从参数中获取正确的类型。您可以使用可变参数模板执行此操作,并且已经有一些流行的实现。