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

佐手、 提交于 2019-12-01 08:54:20
David Rodríguez - dribeas

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 <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

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 <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;
   }
};

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

template <typename Char, typename Traits>
std::basic_ostream<Char,Traits>& 
   std::endl( std::basic_ostream<Char,Traits>& stream );

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

an i have just one overloaded operator method with one parameter(like void*) and then decide inside that method how to typecast integer to char*

No, you can't. A void * carries no type information, so there is no way of working out what type it actually points to.

There is just one overloaded function. It doesn't take a void *, because that would be useless. If it takes one data type, it isn't overloaded, and it only sees the input value after it's been converted to the type. That means you have no control over how to convert, say, an int.

If you want different behavior between, say, an int and a char *, you need to let the function know somehow what type it is getting, and you need to pass the value in. This is exactly what an overloaded or template function does.

is the << operator overloaded for each and every type?

yes

is there a way to achieve it through just one generic overloaded function?

this question doesn't make sense .. do you want just one function, or do you want an overloaded function?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!