how does ofstream or ostream type cast all types to string?

前端 未结 4 1721
庸人自扰
庸人自扰 2021-01-14 07:20

any system defined user type past to ostream object is converted to a string or char* ?

like cout<<4<<\"Hello World\";

works perfectly fine, how

4条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-14 07:48

    After re-reading your question (as a result of a comment in this answer) I have realized that what you want is not only conversions into string (my assumptions in the other answer here), but rather forwarding into the internal ofstream.

    Now, what you want to achieve is not simple, and may be overkill in most cases. In the implementation of [make_string][3] that I have (that forwards to an internal ostringstream), I don't allow for manipulators to be passed. If the user wants to add a new line (we develop under linux) they just pass a '\n' character.

    Your problem is forwarding manipulators (std::hex, std::endl...). Your operator<< is defined as taking a constant instance of a type T, but manipulators are function pointers and the compiler is not able to match it against your methods.

    Manipulators are functions that operate on the std::basic_ostream template. The basic_ostream template and ostream class are defined as:

    template  >
    class basic_ostream;
    
    typedef basic_ostream ostream;
    // or
    // typedef basic_ostream if using wide characters
    

    Then the possible manipulators that can be passed to a std::ostream are:

    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& );
    

    If you want to accept manipulators you must provide that overload in your class:

    class mystream
    {
    //...
    public:
       template  
       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;
       }
    };
    

    In particular, the signature for endl (which may be the only one you require) is:

    template 
    std::basic_ostream& 
       std::endl( std::basic_ostream& stream );
    

    so it falls under the manip1 type of functions. Others, like std::hex fall under different categories (manip3 in this particular case)

提交回复
热议问题