这是可能的,但有点不重要,正确的方法是相当模糊的。
顺便说一句,我会注意到,当你做一些事情时,msg << myval;
只有一个操作数必须是用户定义的类型,这里就是这种情况(即使你没有定义它,anostringstream
仍然是正式的用户-定义类型)。不过,这或多或少无关紧要。现有的过载operator<<
将正常工作;你不需要提供你自己的。
我认为流是“媒人”。您有一个流缓冲区来处理实际的 I/O,还有一个语言环境来处理格式化。这样一想,解决方案就变得相当清楚了:由于您要更改的是格式,并且格式是由语言环境处理的,因此您需要更改语言环境。
然而,语言环境实际上是一个异构集合。具体来说,它是类的集合facet
。在这种情况下,我们关心的切面就是num_put
切面。num_put facet 类具有do_put
各种类型的虚拟成员函数。在这种情况下,我们关心的是double
:
template <class charT, class OutputIterator = std::ostreambuf_iterator<charT> >
class num_put : public std::num_put<charT, OutputIterator> {
public:
virtual iter_type do_put(iter_type i,
std::ios_base& b,
char_type fill,
double v) const
{
if (v == std::numeric_limits<double>().infinity()) {
static const char inf[]="inf";
std::copy(std::begin(inf), std::end(inf), i);
}
else {
std::ostringstream temp;
temp << v;
std::copy(temp.str().begin(), temp.str().end(), i);
}
return i;
}
};
要使用它,您需要为相关流注入包含该方面的语言环境:
int main() {
char *d="0";
std::locale loc(std::locale::classic(), new num_put<char>);
std::cout.imbue(loc);
std::cout << 1.0/atoi(d);
return 0;
}
但是,我应该补充一点,这很快就被拍打在一起了,而且测试非常少。它适用于测试用例,也可能适用于其他狭窄的流。猜测一下,它可能需要更多的工作才能在宽流中正常工作。