Как метод tostream или ostream применяет все типы к строкам?

любой системный определенный пользовательский тип, предшествующий объекту ostream, преобразуется в строку или char *?

как cout < 4 < "Hello World";

отлично работает, как это достигается? представл ет собой < оператор перегружен для каждого типа? есть ли способ достичь этого через одну общую перегруженную функцию? что я имею в виду, могу ли я иметь только один перегруженный операторный метод с одним параметром (например, void *), а затем решить внутри этого метода, как целое число типа to char *

Вещи работали частично, если я перегружал оператор < < используя шаблон i.e

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

поэтому это работает

 UIStream my_stream;
 my_stream<<"bcd"<10;

однако он дает ошибку компилятора, когда я делаю это

my_stream <<endl;

ошибка C2678: двоичная '< <: оператор не найден, который принимает левый операнд типа UIStream (или нет приемлемого преобразования)

Не std:: endl тоже тип объекта?

Ответ 1

После повторного чтения вашего вопроса (в результате комментария в этом ) я понял, что вы хотите не только преобразовать в строку (мои предположения в другом ответе здесь), а скорее переадресовываем во внутренний поток.

Теперь то, что вы хотите достичь, не просто и может быть чрезмерным в большинстве случаев. В реализации [make_string][3], который у меня есть (что переводит к внутреннему ostringstream), я не допускаю, чтобы манипуляторы были переданы. Если пользователь хочет добавить новую строку (мы разрабатываем под Linux), они просто передают символ "\n".

Ваша проблема заключается в перенаправлении манипуляторов (std::hex, std::endl...). Ваш оператор < определяется как принятие постоянного экземпляра типа 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

Тогда возможные манипуляторы, которые могут быть переданы в 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& );

Если вы хотите принять манипуляторы, вы должны указать, что перегрузка в вашем классе:

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

В частности, сигнатура для endl (которая может быть единственной, которая вам нужна):

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

поэтому он подпадает под тип функций manip1. Другие, такие как std::hex, попадают под разные категории (manip3 в этом конкретном случае)

Ответ 2

a У меня есть только один перегруженный оператор метод с одним параметром (например, void *) а затем решить внутри этого метода, как to typecast integer до char *

Нет, вы не можете. Пустота * не содержит информации о типе, поэтому нет способа определить, на какой тип она на самом деле указывает.

Ответ 3

Существует только одна перегруженная функция. Это не принимает void *, потому что это было бы бесполезно. Если он принимает один тип данных, он не перегружен, и он видит только входное значение после его преобразования в тип. Это означает, что вы не можете контролировать, как конвертировать, скажем, int.

Если вам нужно различное поведение между, скажем, int и a char *, вам нужно сообщить функции каким-то образом, какой тип он получает, и вам нужно передать значение. Это именно то, что перегруженная или шаблонная функция.

Ответ 4

обозначает < оператор перегружен для каждого типа?

да

Есть ли способ достичь этого через одну общую перегруженную функцию?

этот вопрос не имеет смысла. Вы хотите только одну функцию или хотите перегруженную функцию?