Каким образом типы ofstream или ostream приводят все типы к строке? - PullRequest
3 голосов
/ 16 июля 2009

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

like cout << 4 << "Hello World"; </p>

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

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

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» (или нет допустимого преобразования) </p>

Разве std :: endl тоже не тип объекта?

Ответы [ 4 ]

11 голосов
/ 16 июля 2009

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

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

Ваша проблема - переадресация манипуляторов (std::hex, std::endl ...). Ваш оператор << определен как постоянный экземпляр типа T, но манипуляторы являются указателями на функции, и компилятор не может сопоставить его с вашими методами. </p>

Манипуляторы - это функции, которые работают с шаблоном 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 голосов
/ 16 июля 2009

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

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

2 голосов
/ 16 июля 2009

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

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

1 голос
/ 16 июля 2009

перегружен ли оператор << для каждого типа? </p>

да

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

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

...