I'm trying to port my own code from VS2012 to g++4.8.
I'm getting this compliation error:
AllocationManager.cpp: In member function ‘void AllocationManager::printMemoryLeaks()’:
TRLogger.h:247:42: error: ‘streamAggrator’ was not declared in this scope
#define TRLOG_INFO streamAggrator(logINFO) << PACKET_DESCRIPTION << __FUNCTION__ << ":" << __LINE__ << ": "
^
AllocationManager.cpp:39:2: note: in expansion of macro ‘TRLOG_INFO’
TRLOG_INFO << "sdfs\n";
Where printMemoryLeaks is a dummy function (AllocationManager is not templated):
void AllocationManager::printMemoryLeaks(void)
{
TRLOG_INFO << "sdfs\n";
}
In the file TRLogger.h:
enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
class streamAggrator
{
public:
streamAggrator(TLogLevel logLevel);
/* private: */
FILELog fLog;
WarnLog wlog;
std::ostringstream& s1;
std::ostringstream& s2;
};
template<typename T>
streamAggrator& operator<<(streamAggrator& agg, const T& obj)
{
agg.s1 << obj;
agg.s2 << obj;
agg.s2.flush();
return agg;
}
....
#define TRLOG_INFO streamAggrator(logINFO) << PACKET_DESCRIPTION << __FUNCTION__ << ":" << __LINE__ << ": "
How can I solve this function - I didn't find any place that I can use this or using to help the compiler.
Thanks,
Guy
Your immediate problem is that you try to pass a temporary streamAggrator object to a function which takes a streamAggrator by non-const reference. You can't bind temporary object to non-const references. The work-around for this problem is to make the output operator member of your streamAggrator: while you cannot bind a temporary to a non-const reference, you can call non-const member functions. Note that you'll also get problems with maniputors like std::flush (the issue there is that these are templates themselves and you actually need to a concrete operator to call them with to have the compiler deduce their template arguments).
Clearly, I would solve the problem properly, i.e., instead of trying to dig about an attempt to a solution which doesn't create a stream, I would create a std::streambuf do do the actual work. Your examples doesn't do anything useful, i.e., I can't really tell what you are trying to do but the code looks remarkably like trying to do something like teestream: write once but send the output to multiple destintations. I have posted corresponding stream buffers quite a few times in the post (mostly on Usenet, though, but I think, at least, once on Stackoverflow, too).
Although I don't know how to get rid of the macro to fill in the __FILE__ and the __LINE__, the actual stream formatting should probably use a stream buffer:
struct teebuf: std::streambuf {
private:
std::streambuf* sb1;
std::streambuf* sb2;
public:
teebuf(std::streambuf* sb1, std::streambuf* sb2): sb1(sb1), sb2(sb2) {}
int overflow(int c) {
this->sb1->sputc(c);
this->sb2->sputc(c);
return std::char_traits<char>::not_eof(c);
}
int sync() {
this->sb1->pubsync();
this->sb2->pubsync();
}
};
class logstream
: std::ostream {
std::ofstream out;
teebuf sbuf;
public:
logstream()
: out("file.log")
, sbuf(out.rdbuf(), std::clog.rdbuf()) {
this->init(&this->sbuf);
}
logstream(logstream&& other)
: out(std::move(other.out))
, sbuf(std::move(other.sbuf)) {
this->init(&this->sbuf);
};
I think you can return the log stream. I don't know what your logging level is meant to do but I guess its processing was removed while preparing the question: it is probably necessary to change the implementation to take the logging level suitably into account.
Related
I want to present a "pattern of mixin based structure"(is this even a term?) but not quite sure if it would hold up in "some situation".
Basic idea is to generate "type using template class" that multiply inherit mixins. So the type declaration would look like: typedef BaseType<Mixin1, Mixin2, MixinN> Type1;
Some accomplishments by the approach:
Type1's special feature like operator overloads and Constructor overloads are always available.
Explicit type casting overhead is abstracted away by BaseType.
C++ multiple implicit conversion barrier is not a problem.
Usual template mixin approach form here looks like: template<class Base> class Printing : public Base {...}. Main drawback for me with this approach:
It is necessary to explicitly cast Printing to Base to use some of Base's special features, Or have to provide those overloads explicitly (I know it would just be a matter of one line of codes). But in some situation it would be irritating.
That is why I have come up with the idea to generate the base.
Please take a look at the implementation ("some situation"):
#include <iostream>
#include <functional>
#ifdef QT_CORE_LIB
#include <QString>
#endif
template<template<class> class... mixin_t>
class StringType : public mixin_t<StringType<mixin_t...>>...
{
std::string _value;
public:
StringType() : _value("") {}
StringType(const StringType &other) = default; // Copy
StringType(StringType &&other) = default; // Move
#ifdef QT_CORE_LIB
StringType(const QString &value) { this->_value = value.toStdString(); }
#endif
StringType(const std::string &value) { _value = value; }
StringType(const char *value) { _value = value; }
template<template<class> class T>
StringType(const StringType<T> &value)
{
_value = static_cast<const std::string &>(value);
}
StringType &operator=(const StringType &rhs) = default; // copy assign
StringType &operator=(StringType &&rhs) = default; // Move assign
#ifdef QT_CORE_LIB
operator QString() const { return QString::fromStdString(_value);}
#endif
operator std::string() const { return _value; }
operator const char *() const{ return _value.c_str(); }
};
template<class this_t> struct _empty_mixn {};
template<class this_t> struct ToStringMixin
{
this_t toString() const { return *static_cast<const this_t *>(this); }
};
template<class this_t> struct StringPrinterMixin
{
void print() const
{
std::cout << "From the printer: " << *static_cast<const this_t *>(this);
}
};
typedef StringType<_empty_mixn> String;
typedef StringType<ToStringMixin> Message;
typedef StringType<ToStringMixin, StringPrinterMixin> PrinterAttachedString;
int main()
{
Message msg1(String("msg1\n"));
std::cout << msg1;
std::cout << "toString() : " << msg1.toString();
Message msg2 = String("msg2\n");
std::cout << msg2;
std::cout << "toString() : " << msg2.toString();
Message msg3(std::string("msg3\n"));
std::cout << msg3;
std::cout << "toString() : " << msg3.toString();
Message msg4 = std::string("msg4\n");
std::cout << msg4;
std::cout << "toString() : " << msg4.toString();
Message msg5("msg5\n");
std::cout << msg5;
std::cout << "toString() : " << msg5.toString();
Message msg6 = "msg6\n";
std::cout << msg6;
std::cout << "toString() : " << msg6.toString();
std::cout << "\n---------------------\n\n";
PrinterAttachedString str1(String("str1\n"));
std::cout << str1;
std::cout << "toString() : " << str1.toString();
str1.print();
PrinterAttachedString str2 = String("str2\n");
std::cout << str2;
std::cout << "toString() : " << str2.toString();
str2.print();
PrinterAttachedString str3(std::string("str3\n"));
std::cout << str3;
std::cout << "toString() : " << str3.toString();
str3.print();
PrinterAttachedString str4 = std::string("str4\n");
std::cout << str4;
std::cout << "toString() : " << str4.toString();
str4.print();
PrinterAttachedString str5("str5\n");
std::cout << str5;
std::cout << "toString() : " << str5.toString();
str5.print();
PrinterAttachedString str6 = "str6\n";
std::cout << str6;
std::cout << "toString() : " << str6.toString();
str6.print();
return 0;
}
So, my questions:
Would it be practical use this in a situation where operator overloading/implicit casting feature necessary?
Does it seem, there would be a necessity of virtual inheritance?
Are there any other implementation like this (My search was a failure)?
Finally, is there a thing called "meta mixin" that would provide a type's special features?
Edit: In response to Phil1970's answer:
I am going to start with the answer to the question 3.
This approach leads to class proliferation: I totally agree. One big drawback I have to admit.
Increases coupling. Not sure how it increases coupling. *1
The rests marked there, I believe is not applicable due to the fact that StringType is quite final. And StringType does not know or about mixed class for real. *1
Now for the answer to the question no 1.
It is usually best to avoid implicit conversion.
The rests to me is ok as long as it is final. *2
With previous question gone (huge thanks to Phil) arose new questions.
*1: It is just one header-only, StringStyle does not depend on mixins and I see no reason to be so. And certainly this it can use private header if somehow becomes necessary. Then how it enforcing coupling?
*2: Just looking for opinions or to get me corrected.
Thanks a lot.
For your question:
It is usually best to avoid implicit conversion. Also you won't be able to reuse std::string operators like +, += with that kind of approach without adding a lot one line function. The wrapper class bring you nothing except adding more conversions as you would then use you new string type and with the mixin approach, this is even worst as you need to also convert between your own types.
Why would you use virtual inheritance? Do you really want to derive from multiple classes that have a common base and that have their own data.
As this is a bad design, you probably won't find many people doing it. Your design increase coupling, lead to class proliferation, increase type conversions and make maintenance harder among other things.
I believe, there is no such thing.
For simple functions like those above, the preferred approach would be to define a namespace (or many if you have a lot of functions that could somehow be categorized like maybe file name manipulation) and then have free functions inside it.
By using a namespace, you have a few advantages:
If you call a lot of functions, you can always add an using statement inside your function or source file (never in a header file).
Auto suggestion will work well to find those function.
If some of the original mixin maintain state, then you should do an helper class. This could be the case for a class like an HTML builder that might have functions like AddTag, Add Attribute, AddEncodedUrl etc that could be used to create an HTML document.
One big advantage of this approach is that coupling is much looser than in your design. For example, a file pair (header and source) would contains all functions used for the Printer. If you need that, you don't have to create a new class that use some combination of mixin.
One big problem with your approach, is that with time you will have a lot of different StringType<…> If you have 5 mixins that could be used, you have 2^5 = 32 classes. At that point, it is almost sure that you will often need the mixin you didn't include and then you have cascading change if the call it deep. And if you use template everywhere then you will have compilation slowdown and probably some code bloat.
Implicit conversion is also considered to be best avoid in most cases by most experts. If you have multiple conversion from and to many classes, at some point you will have unexpected conversion or ambiguities. Making some conversion explicit can limit the problem. Usually is it best to use explicite conversion as it was done by experts in std::string. You have to call member function c_str() if you want a C style string.
For example, since your StringType class define conversion to both const char * and QString, then if you have a method that accept both (maybe an Append function), then you have a conflict.
If you really want conversion, then use named method instead (for ex. AsQString(), c_str(), tostdstring()...). It help ensure that all conversion are intended. It make it easier to find them and it is certainly better that explicit cast like you have done in a few place in your code. While static_cast and other casts are sometime useful, then can also hide some problem when code is refactored as in some case, the cast might compile while not being correct. This would be the case if you cast to a derived class and at some point decide to change the derived class for something else and forget to update some casts.
You should select the most appropriate string for your application and do conversion when required. In a large application, you might use one type for the UI (ex. CString or QString) while using standard string in librairies that are shared across platforms or with third party library. Some time those libraries have their own string class too. Your selection should try minimize useless conversions.
We have an existing log macro in our code. Lets call it LOG_XXX where XXX is the log level to use, such as LOG_INFO, LOG_DEBUG, LOG_ERROR etc. We stream log messages to the macro:
LOG_INFO << "This is a log message.";
Under the covers, the macro creates a temporary object that exposes a stream. When the object is destroyed the logger is called with the stream contents.
As our codebase grows, we want to add structured logging with key value pairs. We would also like to add a mandatory "module name" to the macro, forcing callers to specify what logical module in the software is doing the logging.
LOG_INFO("some module) << make_pair("RequestId", "foo") << make_pair("Msg", "This is a log message.");
I can implement this by creating a different object whose constructor takes the module name, and overloads the << operator to take string pairs.
Now I can name this new macro LOG_INFO2 and be done with it. But that name feels ugly to me. What this really is conceptually is an overload, but macros can't be overloaded.
One route is to implement a selector that picks the right macro based on the number of arguments. But since the original call sites have no parantheses LOG_INFO(), I don't think this will work. I previously asked this question about it.
I can make callers directly instantiate the object but they shouldn't have to know what the object implementing all of this is:
LogWriter(module, LogLevel.Info) << make_pair("Msg", "This is a log message");
My overall goal is to not have to edit the original calls, and add the new functionality. Are there options other than the ones I've thought of? Is there something about the macro selection option that I am doing wrong?
You may change your macro to return an object with operator ()(const std::string&), something like:
struct Logger2
{
explicit Logger2(const std::string& name) : name(name) {}
Logger2& operator << (const std::pair<const char*, const char*>& p)
{
std::cout << name << ":" << p.first << " " << p.second << std::endl;
return *this;
}
std::string name;
};
struct Logger
{
Logger& operator << (const std::string& s)
{
std::cout << "Log:" << s << std::endl;
return *this;
}
Logger2 operator () (const std::string& name) const
{
return Logger2{name};
}
};
#define LOG Logger{}
Live Demo
This works:
stringstream temp;
temp << i;
result_stream << transform(temp.str());
(transform is a function that takes a string and returns a string; i is an int). However, my attempt to let C++11 create a temporary object without a name didn't work:
result_stream << transform((stringstream() << i).str());
I thought it would work, since the second << should just return the first argument and I'd be able to use str() on that. But I get this error:
error: 'class std::basic_ostream<char>' has no member named 'str'
I'm using g++ 4.8.1 (MinGW-W64).
Is there a way to accomplish this (i.e. write code like this using an unnamed temporary)? (The above code is a bit simplified, and the actual code involves using << on arguments other than int.)
This doesn't work because the second << is std::ostream &operator<<(std::ostream &, int); and so the return type is ostream& which has no member str().
You would have to write:
result_stream << transform( static_cast<stringstream &>(stringstream() << i).str() );
Update (2019): According to LWG 1203 the standard may be changed in future (and one major implementation already has) so that this code no longer works, and a simpler code works instead. See this question for detail.
In the interim period, apparently the following works on both old and new:
result_stream << transform( static_cast<stringstream &>(stringstream().flush() << i).str() );
// ^^^^^^^^
This should not be a performance penalty since flushing an empty stream has no effect...
operator<<() returns a reference to the base class std::ostream contained within the std::stringstream. The base class doesn't contain the str() method. You can cast it back down to a std::stringstream&:
result_stream << transform(static_cast<std::stringstream&>(std::stringstream() << i).str());
The result of the << operator on the temporary stringstream is an ostream. There is no str() method on an ostream.
Use to_string instead:
using std::to_string;
result_stream << transform(to_string(i));
You can define a helper to_string to handle objects not covered by std::to_string.
template <typename T>
std::string to_string (const T &t) {
std::ostringstream oss;
oss << t;
return oss.str();
}
For example, if you had a class Foo that understood redirection to an ostream, and f was an instance of Foo, then you could do:
result_stream << transform(to_string(f));
Try it online!
If you actually want to use a lot of redirection to build up a string before transforming, you could create a helper object for that as well.
struct to_string_stream {
std::ostringstream oss;
template <typename T>
auto & operator << (const T &t) { oss << t; return *this; }
operator std::string () const { return oss.str(); }
void clear () { oss.string(std::string()); }
};
Then, you could do something like:
to_string_stream tss;
result_stream << transform(tss << i << ':' << f);
Try it online!
Tried and failed to do this for C++11 (in 2009):
http://cplusplus.github.io/LWG/lwg-active.html#1203
libc++ went outlaw and implemented it anyway.
It is up for reconsideration, but can not possibly be standardized prior to 2017 (standardization is a glacial process).
I don't know why this is erroring, but I'm just trying to add something "akin" to endl so that I can throw what's in an ostringstream to our debugger. I have the following:
class debug_stream_info
{
public:
debug_stream_info(int errorLine, char *errorFile, int level)
:m_errorLine(errorLine), m_errorFile(errorFile), m_logLevel(level)
{
}
friend std::basic_ostringstream<char>& operator<<(std::basic_ostringstream<char>& os, debug_stream_info& debug_info);
private:
int m_errorLine;
std::string m_errorFile;
int m_logLevel;
};
std::basic_ostringstream<char>& operator<<(std::basic_ostringstream<char>& os, debug_stream_info& debug_info)
{
// Write the stream's contents to cpu_debug
// Deleted custom logging function. No errors here though
// Clear the stream for re-use.
os.str("");
os.seekp(0);
return os;
}
int main(int argc, char** argv)
{
std::ostringstream myout;
myout << "hey there" << " and some more " << "Numbers!!: " << 435 << 54.2 << " that's good for numbers" << debug_stream_info(__LINE__, __FILE__, LOG_LEVEL);
return 0;
}
The error I'm getting is: error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'debug_stream_info' (or there is no acceptable conversion) for the line in main. This is on VS2008.
I'm including sstream, iostream, etc, and have the namespaces set up right. I'm getting no other errors. I even tried replacing all occurrances of basic_ostream with just ostringstream and there was no difference (I'll be having a w_char version later, but I wanted the simple case to work first). I made the object on the line above and then passed a fully-constructed object on the line, and the error was exactly the same. I've changed the signature of the second argument to and from const with no change as well.
Any ideas on what I'm doing wrong here?
Edit: since EVERY response seems to want to put it there, I can NOT use std::ostream because I want this to work ONLY for std::ostringstream (and std::basic_ostringstream) and not for any type of output stream. Besides, the function wouldn't compile with ostream anyways, since I'm using the os.str() method, which isn't in ostream, only the sub-classes.
The real problem with your code is that you've overloaded std::ostringstream rather than std::ostream. So your code would work if you write this:
debug_stream_info info(/** blah blah**/);
std::ostringstream oss;
oss << info ; //OK
However this will not work:
oss << 1 << info; //ERROR
This is compilation error because the expression oss<<1 returns an object of type std::ostream& which doesn't have overload which takes debug_stream_info as second argument. That means if you use cast as:
static_cast<std::ostringstream&>(oss << 1) << info; //OK
then that should work again.
So the solution is to overload std::ostream, instead of std::basic_ostringstream.
Also, the second parameter should be const & . This is also a problem with your code.
So write this:
std::ostream& operator<<(std::ostream&, debug_stream_info const &);
//^^^^^^^ note this
The second parameter should be const & so that you could write temporary objects to the stream.
debug_stream_info(__LINE__, __FILE__, LOG_LEVEL); is creating unnamed object which is not returning anything hence error
#include <iostream>
#include <cstdio>
#include <sstream>
using namespace std;
class debug_stream_info
{
public:
debug_stream_info(int errorLine, char *errorFile, int level)
:m_errorLine(errorLine), m_errorFile(errorFile), m_logLevel(level)
{
}
friend std::basic_ostringstream<char>& operator<<(std::basic_ostringstream<char>& os, debug_stream_info& debug_info);
std::ostringstream& fun(std::ostringstream& os)
{
os<<"Ashish"<<endl;
return os;
}
private:
int m_errorLine;
std::string m_errorFile;
int m_logLevel;
};
std::basic_ostringstream<char>& operator<<(std::basic_ostringstream<char>& os, debug_stream_info& debug_info)
{
// Write the stream's contents to cpu_debug
// Deleted custom logging function. No errors here though
// Clear the stream for re-use.
// os.str("");
// os.seekp(0);
return os;
}
int main(int argc, char** argv)
{
std::ostringstream myout, test;
myout << "hey there" << " and some more " << "Numbers!!: " << 435 << 54.2 << " that's good for numbers"
<< debug_stream_info(1, "/home/ashish/test", 1).fun(test);
return 0;
}
Nawaz has explained very clearly why you're getting the error. The
usual solution in this case is to define your own stream type, unrelated
to std::istream. Something along the lines of:
class DebugStream
{
std::ostringstring* collector;
public:
template <typename T>
DebugStream& operator<<( T const& value )
{
if ( collector != NULL ) {
*collector << value;
}
return *this;
}
};
There are infinite variations on this; in your case, you could add a
non-template member function for your type; more likely, you'd add a
constructor which took the same arguments:
DebugStream( int lineNumber, std::string const& filename, int logLevel )
: collector( isActive( logLevel ) ? new std::ostringstream : NULL )
{
// Initial insertion of lineNumber, filename, timestamp...
}
You can also add a destructor which atomically flushes the collected
data to a file (or sends an email, or writes it to the system log, or
whatever). (Be very careful about this. You don't want an exception to
escape from the destructor, even if the logging fails.)
Finally, you might want to use a custom streambuf, rather than
stringstream. Say one that keeps the allocated buffer from one
instance to the next. And if you do this, rather than newing the
stream each time, you might pick up an instance from a table, indexed by
the log level (and initialized from a configuration file).
I would like to be able to do:
foo(stringstream()<<"number = " << 500);
EDIT: single line solution is crucial since this is for logging purposes. These will be all around the code.
inside foo will print the string to screen or something of the sort.
now since stringstream's operator<< returns ostream&, foo's signature must be:
foo(ostream& o);
but how can I convert ostream& to string? (or char*).
Different approaches to achieving this use case are welcome as well.
The obvious solution is to use dynamic_cast in foo. But the given
code still won't work. (Your example will compile, but it won't do what
you think it should.) The expression std::ostringstream() is a
temporary, you can't initialize a non-const reference with a temporary,
and the first argument of std::operator<<( std::ostream&, char const*)
is a non-const reference. (You can call a member function on a
temporary. Like std::ostream::operator<<( void const* ). So the code
will compile, but it won't do what you expect.
You can work around this problem, using something like:
foo( std::ostringstream().flush() << "number = " << 500 );
std::ostream::flush() returns a non-const reference, so there are no
further problems. And on a freshly created stream, it is a no-op.
Still, I think you'll agree that it isn't the most elegant or intuitive
solution.
What I usually do in such cases is create a wrapper class, which
contains it's own std::ostringstream, and provides a templated
member operator<< which forwards to the contained
std::ostringstream. Your function foo would take a const
reference to this—or what I offen do is have the destructor call
foo directly, so that the client code doesn't even have to worry about
it; it does something like:
log() << "number = " << 500;
The function log() returns an instance of the wrapper class (but see
below), and the (final) destructor of this class calls your function
foo.
There is one slight problem with this. The return value may be copied,
and destructed immediately after the copy. Which will wreck havoc with
what I just explained; in fact, since std::ostringstream isn't
copyable, it won't even compile. The solution here is to put all of the
actual logic, including the instance of std::ostringstream and the
destructor logic calling foo in a separate implementation class, have
the public wrapper have a boost::shared_ptr to it, and forward. Or
just reimplement a bit of the shared pointer logic in your class:
class LogWrapper
{
std::ostringstream* collector;
int* useCount;
public:
LogWrapper()
: collector(new std::ostringstream)
, useCount(new int(1))
{
}
~LogWrapper()
{
-- *useCount;
if ( *useCount == 0 ) {
foo( collector->str() );
delete collector;
delete useCount;
}
}
template<typename T>
LogWrapper& operator<<( T const& value )
{
(*collector) << value;
return *this;
}
};
Note that it's easy to extend this to support optional logging; just
provide a constructor for the LogWrapper which sets collector to
NULL, and test for this in the operator<<.
EDITED:
One other thing occurs to me: you'll probably want to check whether the
destructor is being called as a result of an exception, and not call
foo in that case. Logically, I'd hope that the only exception you
might get is std::bad_alloc, but there will always be a user who
writes something like:
log() << a + b;
where the + is a user defined overload which throws.
I would suggest you to use this utility struct:
struct stringbuilder
{
std::stringstream ss;
template<typename T>
stringbuilder & operator << (const T &data)
{
ss << data;
return *this;
}
operator std::string() { return ss.str(); }
};
And use it as:
void f(const std::string & s );
int main()
{
char const *const pc = "hello";
f(stringbuilder() << '{' << pc << '}' );
//this is my most favorite line
std::string s = stringbuilder() << 25 << " is greater than " << 5 ;
}
Demo (with few more example) : http://ideone.com/J995r
More on my blog : Create string on the fly just in one line
You could use a proxy object for this; this is a bit of framework, but if you want to use this notation in a lot of places then it may be worth it:
#include <iostream>
#include <sstream>
static void foo( std::string const &s )
{
std::cout << s << std::endl;
}
struct StreamProxy
{
std::stringstream stream;
operator std::string() { return stream.str(); }
};
template <typename T>
StreamProxy &operator<<( StreamProxy &s, T v )
{
s.stream << v;
return s;
}
static StreamProxy make_stream()
{
return StreamProxy();
}
int main()
{
foo( make_stream() << "number = " << 500 );
}
This program prints
number = 500
The idea is to have a little wrapper class which can be implicitely converted into a std::string. The << operator is simply forwarded to the contained std::stringstream. The make_stream() function is strictly speaking not necessary (you could also say StreamProxy(), but I thought it looks a bit nicer.
A couple of options other than the nice proxy solution just presented by Frerich Raabe:
Define a static string stream variable in the header that defines the logging function and use the comma operator in your invocation of the logging function so that this variable is passed rather than the ostream& returned by the stream insertion operator. You can use a logging macro to hide this ugliness. The problem with this solution is that it is a bit on the ugly side, but this is a commonly used approach to logging.
Don't use C++ I/O. Use a varargs C-style solution instead. Pass a format string as the first argument, with the remaining arguments being targets for that format string. A problem with this solution is that even if your compiler is smart enough to ensure that printf and its cousins are safe, the compiler probably won't know that this new function is a part of the printf family. Nonetheless, this is also a commonly used approach.
If you don't mind using macros functions, you can make the logging function accept const string&, and use the following macro
#define build_string(expr) \
(static_cast<ostringstream*>(&(ostringstream().flush() << expr))->str())
And suppose you foo has signature void foo(const string&), you only need the one-liner
foo(build_string("number = " << 500))
This was inspired by James Kanze's answer about static_cast and stringstream.flush. Without the .flush() the above method fails with unexpected output.
Please note that this method should not leak memory, as temporary values, whether in the pointer form or not, are still allocated on the stack and hence destroyed upon return.
Since you're converting to string anyways, why not
void foo(const std::string& s)
{
std::cout << "foo: " << s << std::endl;
}
...
std::stringstream ss;
ss << "number = " << 500;
foo(ss.str());
This is not possible. As the name ostream implies, it is used for output, for writing to it. You could change the parameter to stringstream&. This class has the method str() which returns a std::string for your use.
EDIT I did not read the issue with operator << returning ostream&. So I guess you cannot simply write your statements within the functions argument list but have to write it before.
You can create a small wrapper around std::ostringstream that will convert back to std::string on use, and have the function take a std::string const &. The first approach to this solution can be found in this answer to a different question.
On top of that, you can add support for manipulators (std::hex) if needed.