Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > перегрузить оператор вывода в строку


Автор: boostcoder 3.4.2011, 12:35
всем доброго дня.

есть надобность выводить не в поток вывода, а в строку.
обычно вывожу в std::stringstream и методом str() получаю строку.

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

std::string str;
str << "chars" << 1234 << 3.14159265;

какие варианты есть?

спасибо  smile 

Автор: mes 3.4.2011, 12:49
решение в лоб : 
Код

template <typename T>
std::string& operator << (std::string& str, T const& obj)
{
   std::ostringstream os;
   os << str << obj;
   
   str = os.str ();   
   return str;
}

http://liveworkspace.org/code/6ee83fd38547e246f6351f77f387a06a

Автор: boostcoder 3.4.2011, 12:56
mes, спасибо.
я рассматривал такой вариант, но почему-то подумал что оператор вывода в таком случае должен возвращать stringstream&
и недодумал.. поспешил с вопросом.

вопрос закрыт.

Добавлено @ 12:58
mes, еще такой вопрос.
не понимаю, что в следующем коде не так?..
Код

#include <iostream>
#include <sstream>

template <typename T>
std::string& operator << (std::string& str, T const& obj) {
   std::ostringstream os;
   os << str << obj;
   
   str = os.str ();   
   return str;
}

void print(const std::string& str) {
   std::cout << str << std::endl;
}

int main() {
   print(std::string() << "ab, " << 23 << ", " << 3.14159265);
}


http://liveworkspace.org/code/d1e3007290cd785b083cfc64321da742

Добавлено @ 13:00
ведь результат выражения "std::string() << "ab, " << 23 << ", " << 3.14159265" - строка

Автор: mes 3.4.2011, 13:02
Цитата(boostcoder @  3.4.2011,  11:56 Найти цитируемый пост)
в следующем коде не так?..

грубо : rvalue не может быть присвоена не константной ссылке.. 

http://liveworkspace.org/code/ed9df98b42272d53cbfa22f845980c07

Добавлено через 46 секунд
Цитата(boostcoder @  3.4.2011,  11:56 Найти цитируемый пост)
вопрос закрыт.

а зря, не очень удачное решение.. 

Автор: boostcoder 3.4.2011, 13:04
Цитата(mes @  3.4.2011,  13:02 Найти цитируемый пост)
а зря, не очень удачное решение..

что с этим решением не так? есть варианты получше? ;)

Автор: mes 3.4.2011, 13:05
Цитата(boostcoder @  3.4.2011,  12:04 Найти цитируемый пост)
есть варианты получше?

для получше надо подумать.. но должно быть.. 

Автор: mes 3.4.2011, 17:49
вот так имхо по-безопасней, да  и по логичней будет :
http://liveworkspace.org/code/d8dde9cde2392a2ee30fa2072feebc34

Код

template <typename T>
std::string operator && (std::string const& str, T const& obj)
{
   std::ostringstream os;
   os << str << obj;
   
   return os.str();
}


Автор: boostcoder 3.4.2011, 17:57
Цитата(mes @  3.4.2011,  17:49 Найти цитируемый пост)
operator &&

эм... как-то смущает..

Автор: mes 3.4.2011, 18:01
Цитата(boostcoder @  3.4.2011,  16:57 Найти цитируемый пост)
эм... как-то смущает..

a какой оператор лучше отражает концепцию concat ? 

Автор: boostcoder 3.4.2011, 18:02
Цитата(mes @  3.4.2011,  18:01 Найти цитируемый пост)
a какой оператор лучше отражает концепцию concat ? 

оператор вывода.

Автор: mes 3.4.2011, 18:04
Цитата(boostcoder @  3.4.2011,  17:02 Найти цитируемый пост)
оператор вывода. 

<< ?  так посмотрите на действие функции.. она не делает _вывода_ smile

Автор: mes 3.4.2011, 18:58
Код

template <typename T>
std::string operator && (std::string const& lhs, T const& obj) {

   std::ostringstream os;
   os << rhs;
   
   return lhs + os.str();
}
std::string operator && (std::string const& lhs, std::string const& rhs) {
   return lhs + rhs;
}
 
std::string operator && (std::string const& lhs, const char* rhs) {
   return lhs + rhs;
}


Добавлено @ 18:59
вместо && можно & или ,  если удобнее.. 

Автор: boostcoder 3.4.2011, 19:00
Цитата(mes @  3.4.2011,  18:04 Найти цитируемый пост)
она не делает _вывода_

она делает вывод в строку smile

Автор: mes 3.4.2011, 19:06
Цитата(boostcoder @  3.4.2011,  18:00 Найти цитируемый пост)
она делает вывод в строку

нет, она возвращает новую строку, как результат объединения/слияния двух аргументов..

Добавлено через 43 секунды
первоначальная строка остается неизмененной..

Добавлено через 4 минуты и 57 секунд
именно возвращение ссылки в первоначальном коде и было слабым местом реализации .. 

Автор: volatile 3.4.2011, 19:17
mes, мне ваш первый вариант больше понравился
Код

template <typename T>
std::string& operator << (std::string& str, T const& obj)
{
   std::ostringstream os;
   os << obj;
   str += os.str ();   
   return str;
}

по крайней мере он отвечал на первый вопрос:
Цитата(boostcoder @  3.4.2011,  12:35 Найти цитируемый пост)
чтоб использовать так:
std::string str;
str << "chars" << 1234 << 3.14159265;


Автор: mes 3.4.2011, 19:20
Цитата(volatile @  3.4.2011,  18:17 Найти цитируемый пост)
по крайней мере он отвечал на первый вопрос:

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

Добавлено @ 19:22
тем более что второй вопрос оправдывает мои сомнения 
Цитата(boostcoder @  3.4.2011,  11:56 Найти цитируемый пост)
не понимаю, что в следующем коде не так?..
 
Код

print(std::string() << "ab, " << 23 << ", " << 3.14159265 );


 smile 

Автор: boostcoder 3.4.2011, 19:24
Цитата(mes @  3.4.2011,  19:06 Найти цитируемый пост)
она возвращает новую строку, как результат объединения/слияния двух аргументов..

ну да. но как результат - получаем что нужно.

Автор: volatile 3.4.2011, 19:28
Ну в принципе можно оставить оба, они друг другу не мешают  smile 
Но все же первый я возьму себе в копилку.

Автор: mes 3.4.2011, 19:44
Цитата(boostcoder @  3.4.2011,  18:24 Найти цитируемый пост)
ну да. но как результат - получаем что нужно. 

оно разное и пример с print _подверждает_ это.. smile

Цитата(volatile @  3.4.2011,  18:28 Найти цитируемый пост)
Но все же первый я возьму себе в копилку. 

только осторожней  smile 

Автор: boostcoder 3.4.2011, 19:49
Цитата(mes @  3.4.2011,  19:44 Найти цитируемый пост)
оно разное

что разное? не въезжаю...

Автор: mes 3.4.2011, 19:58
Код

str << 1
str && 2


в случае 1 : rvalue записывается в lvalue str
в случае 2:  из двух rvalue получается третья rvalue

ну и соответственно разные применение и требования.. 


Автор: boostcoder 8.4.2011, 21:13
реализовал так:
Код

#include <string>
#include <iostream>
#include <boost/format.hpp>

struct log_formater {
   log_formater(const std::string& format, const char* file, size_t line, const char* function)
      :_format(format),
      _file(file),
      _line(line),
      _function(function)
   {}

   ~log_formater() {
      std::cout << _file << "(" << _line << "): " << _function << "| " << _format.str() << std::endl;
   }

   template <typename T>
   log_formater& operator% (const T& value) {
      _format % value;
      return *this;
   }

private:
   boost::format _format;
   const char* _file;
   size_t _line;
   const char* _function;
};

#define LOG_MESSAGE(str) log_formater(str, __FILE__, __LINE__, __PRETTY_FUNCTION__)

void function(std::pair<std::vector<std::string>, int>& arg) {
   LOG_MESSAGE("message arg1-%1%, arg2-%2%") % 34 % 43;
}

int main() {
   LOG_MESSAGE("simple log message");
   std::pair<std::vector<std::string>, int> farg;
   function(farg);
}

http://liveworkspace.org/code/f43be67a24747f1c7750755644358655

всем спасибо.

Автор: mes 8.4.2011, 22:52
Цитата(boostcoder @  8.4.2011,  20:13 Найти цитируемый пост)
реализовал так:

вот вроде то же самое, но меньше строчек кода :
http://liveworkspace.org/code/e5e3276a6674547631f19c76e6a91b7d
smile

Автор: boostcoder 8.4.2011, 22:55
mes, да, это получше будет. и по быстрее. спасибо smile 

Автор: mes 8.4.2011, 23:14
Цитата("boostcoder")

за оптимизацию кода+++

ну оптимизации то там как таковой и не было, просто выкинил все лишнее, что Вы туда впихнули  smile 

Автор: boostcoder 8.4.2011, 23:19
кода меньше + результат тот же = оптимизация. по любому ;)

Автор: mes 9.4.2011, 15:26
Цитата(boostcoder @  8.4.2011,  22:19 Найти цитируемый пост)
кода меньше + результат тот же = оптимизация. по любому ;)

как по мне, то устранение_пессимизации   и оптимизация разные хотя и смежные понятия..  smile 
но в любом случае это не тема для спора smile

Автор: boostcoder 8.5.2011, 19:22
попробовал скомпилить код с отключенной отладкой, и улыбнулся.
все что после закрывающейся скобки макроса, остается ведь smile 
Код

#ifndef DISABLE_LOGGING
#define LOG_MESSAGE(str) _тут_всякий_код_инлайнящийся_в_код_
#else
#define LOG_MESSAGE(str)
#endif


нужно и аргументы в макрос писать. а для этого нужен variadic_macros. разбираюсь...

Автор: mes 9.5.2011, 00:49
Цитата(boostcoder @  8.5.2011,  18:22 Найти цитируемый пост)
 с отключенной отладкой, и улыбнулся.

 smile  smile  smile  smile 

Цитата(boostcoder @  8.5.2011,  18:22 Найти цитируемый пост)
а для этого нужен variadic_macros. разбираюсь... 

а если так : http://liveworkspace.org/code/85de8371fccd890758001c0d182d26ba ?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)