C ++标准库是否具有printf转换说明符的模板化getter?

时间:2016-03-25 09:41:28

标签: c++ c++-standard-library format-specifiers

众所周知,如果由于某种原因你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;。

3 个答案:

答案 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);

其中%只从参数中获取正确的类型。您可以使用可变参数模板执行此操作,并且已经有一些流行的实现。