我想覆盖
operator<<
,这样:
double d = 3.0;
mycustomstringstream << "Hello World " << d << "what a nice day.";
std::cout << mystream.str() << std::endl;
将产生输出:
Hello World (double)(3.00000000000)what a nice day.
既然像这样打印
double
就可以了,所以我大胆地实现了:
std::ostream& operator<<(std::ostream& o, double const& d){
o<<"(double)("<< d << ")";
return o;
}
这不起作用,因为编译器会解释歧义(因为该运算符已经定义)。
就像一开始一样,我可以继承
std::stringstream
并只需替换我的 customstringstream
的该运算符的定义:
#include <sstream>
class MyCustomStringStream: public std::stringstream{};
MyCustomStringStream& operator<<(MyCustomStringStream& o, double const& d){
o<<"(double)("<< ( (std::stringstream)(o) << d ) << ")";
return o;
}
这是错误:
error: use of deleted function 'std::__cxx11::basic_stringstream<_CharT, _Traits, _Alloc>::basic_stringstream(const std::__cxx11::basic_stringstream<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'
那么那么:
#include <iostream>
#include <sstream>
class MyStringStream: public std::stringstream{
std::stringstream aux;
public:
MyStringStream& operator<<(double const& d){
aux.str() = "";
aux << std::scientific << "((double)(" << d << ")";
*this << aux.str();
return *this;
}
};
int main() {
double d = 12.3;
MyStringStream s;
s << "Hello World " << d << "what a nice day.";
std::cout << s.str() << std::endl;
}
但这仍然打印:
Hello World 12.3what a nice day.
无论你怎么想,继承通常都不是问题。无论如何,我不会从流派生(通常不建议从 STL 类型继承,尽管流允许这样做)。 对于您的情况,有一个更可重用的解决方案,制作一个辅助格式化对象(演示:https://onlinegdb.com/PKtw7P3E8)。
至少使用这种(C++17)方法,您仍然可以混合正常格式和科学格式(并且在代码中仍然有一个中心点,您可以在其中管理格式应该是什么样子)。 对于 C++20,有一个格式库可以帮助您使用自定义格式化程序
#include <iostream>
#include <sstream>
template<typename type_t>
struct as_scientific
{
explicit as_scientific(type_t& v) : value{v}{};
type_t value;
};
template<typename type_t>
std::ostream& operator<<(std::ostream& os, const as_scientific<type_t>& scientific)
{
os << std::scientific << "((" << typeid(type_t).name() << ")(" << scientific.value << ")";
return os;
}
int main()
{
double d = 12.3;
std::ostringstream s;
s << "Hello World " << as_scientific{d} << "what a nice day.";
std::cout << s.str() << "\n";
// or directly
std::cout << as_scientific{d} << "\n";
}