ofstream或ostream类型如何将所有类型转换为字符串?

Kaz*_*oom 3 c++ operator-overloading operators operator-keyword

任何系统定义的用户类型过去到ostream对象都转换为字符串或char*?

喜欢cout << 4 <<"Hello World";

工作得非常好,这是如何实现的?是每个类型的<<运算符重载?有没有办法通过一个通用的重载函数实现它?我的意思是我可以只有一个带有一个参数的重载运算符方法(如void*),然后在该方法内部决定如何将整数转换为char*

如果我重载operator <<使用模板ie,事情部分工作

class UIStream
{
private:
 ofstream stream;
public:
 UIStream();
 ~UIStream();
 template <typename T>
 UIStream& operator << (const T);
};
Run Code Online (Sandbox Code Playgroud)

这样可行

 UIStream my_stream;
 my_stream<<"bcd"<10;
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时它会给编译器错误

my_stream <<endl;
Run Code Online (Sandbox Code Playgroud)

错误C2678:二进制'<<':找不到哪个运算符带有'UIStream'类型的左操作数(或者没有可接受的转换)

std :: endl也不是一种对象吗?

Dav*_*eas 11

重新阅读您的问题(如本评论的结果后回答)我已经意识到,你想要的不仅是转换成字符串(我在对方的回答假设在这里),而是转发到内部ofstream的.

现在,你想要达到的目标并不简单,在大多数情况下可能会有些过分.在[make_string][3]我的实现(转发到内部ostringstream),我不允许传递操纵器.如果用户想要添加一个新行(我们在linux下开发),他们只需传递一个'\n'字符.

你的问题是转发操纵器(std::hex,std::endl...).您的operator <<被定义为采用类型T的常量实例,但操纵符是函数指针,编译器无法将其与您的方法匹配.

操纵器是在std::basic_ostream模板上操作的功能.该basic_ostream模板ostream类的定义如下:

template <typename TChar, typename TTraits = char_traits<TChar> >
class basic_ostream;

typedef basic_ostream<char> ostream;
// or
// typedef basic_ostream<wchar_t> if using wide characters
Run Code Online (Sandbox Code Playgroud)

然后可以传递给std :: ostream的可能操纵器是:

typedef std::ostream& (*manip1)( std::ostream& );

typedef std::basic_ios< std::ostream::char_type, std::ostream::traits_type > ios_type;
typedef ios_type& (*manip2)( ios_type& );

typedef std::ios_base& (*manip3)( std::ios_base& );
Run Code Online (Sandbox Code Playgroud)

如果你想接受操纵器,你必须在你的类中提供过载:

class mystream
{
//...
public:
   template <typename T> 
   mystream& operator<<( T datum ) {
      stream << datum;
      return *this
   }
   // overload for manipulators
   mystream& operator<<( manip1 fp ) {
      stream << fp;
      return *this;
   }
   mystream& operator<<( manip2 fp ) {
      stream << fp;
      return *this;
   }
   mystream& operator<<( manip3 fp ) {
      stream << fp;
      return *this;
   }
};
Run Code Online (Sandbox Code Playgroud)

特别是,endl的签名(可能是您需要的唯一签名)是:

template <typename Char, typename Traits>
std::basic_ostream<Char,Traits>& 
   std::endl( std::basic_ostream<Char,Traits>& stream );
Run Code Online (Sandbox Code Playgroud)

所以它属于manip1功能类型.其他人,如std::hex属于不同类别(manip3在这种特殊情况下)