Перегрузка << для определения манипуляторов - PullRequest
0 голосов
/ 17 июля 2009

Я нашел этот вопрос в архивном файле на joelonsoftware.com http://discuss.joelonsoftware.com/default.asp?joel.3.594503.11

"Привет,

У меня особенно медленный день и не могу опередить оператора проблема перегрузки. Я хотел бы класс, чтобы иметь возможность принимать данные через оператор диссертации, т.е.:

myClassInstance << std :: string ("a строка ") << 4 << 3.4 << std :: endl; </p>

Внутренне, я бы хотел, чтобы все закончилось вверх в потоке строки, чтобы я мог тогда переправить его в другие потоки (скажем, std :: cout и ofstream). у меня есть ужасно запутался, как я могу это сделать без необходимости писать оператор << перегрузка для каждого типа данных и как входной поток будет создан на первый вызов (myClassInstance << ...). </p>

Любая помощь с благодарностью получена! "

Это именно то, что я пытаюсь сделать. Я нашел свой способ работы со всеми типами, определив шаблоны и другой перегруженный метод для работы с манипуляторами, такими как endl, определенный в классе ostream.

UIStream&  UIStream ::operator << (const T str)
 {
     CString cstr(stringify(str).c_str());
     theFrame->m_pOutputView->WriteMessage(cstr);
     return *this;
 }

 //for manipulators like std::endl
UIStream&  UIStream ::operator <<(ostream& (*m)(ostream&))
{
     //stream<<*m; 
     //CString cstr((*m)(new ostream).c_str());
    if(*m==&std::endl);
        theFrame->m_pOutputView->WriteMessage("\n");
     return (*this);
}

Я все еще борюсь с манипуляторами, которые принимают аргументы, такие как hex dec или oct, которые определены в ios_base.

Ответы [ 4 ]

3 голосов
/ 17 июля 2009

Вероятно, идея прочитать хорошую книгу на эту тему. Я рекомендую Стандартные потоки и локали IOS C ++ от Langer и Kreft.

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

Чтобы заставить ваш поток работать с манипуляторами, которые принимают аргументы, не так просто, как когда они не имеют аргументов. Проблема в том, что манипулятор будет иметь вид

ImpDefClass manipulator( argument list );

, где ImpDefClass - это, как следует из названия, класс, определенный реализацией. Например, в моей системе setprecision объявлено как

inline _Setprecision setprecision(int __n);

где _Setprecision - это просто struct, который определяет моя реализация.

Поэтому проблема в том, что вы не можете просто написать новый оператор потока, такой как

UIStream& operator<<( UIStream&, XXX );

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

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

Я бы хотел просто включить std :: stringstream в MyClass и перегрузить <<, чтобы принять MyClass в качестве lhs и что-нибудь в качестве RHS. </p>

class MyClass {
public:
   template <class T>
   MyClass & operator <<(const T & rhs) {
       m_stream << rhs;
       return *this;
    }
    private:
        std::ostringstream m_stream;
};

edit: Я думаю, это не совсем то, что вы ищете. Тем не менее, может быть полезно для более простого использования.

0 голосов
/ 17 июля 2009

Чем больше вопросов вы задаете, тем больше я убежден, что правильный подход к вашей проблеме - написание нового потокового буфера. В сети есть документация для этого - объяснение здесь было бы слишком длинным для меня - и есть библиотека boost, называемая iostreams, которая может вам помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...