471,075 Members | 706 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,075 software developers and data experts.

operator << for std::string in #define

I am using a message handler class that implements amongst others:

static void message ( std::string aHeader,
std::string aMessage,
int aTimeout = 0,
MessageType aFlag =
MSG_Information );

I then use a set of defines, e.g.:

#define USR_MSG( msg ) MSG::message( "", msg, 0, MSG_User )

The problem is now that I get a compiler error when I write

USR_MSG("The value of x is " << x);

Does anybody have a smart solution for that? I thought about rerouting
std::cout but it doesn't seem to be the best way to me.

Thanks a lot for your help,

Martin.

May 8 '07 #1
5 2375
On May 8, 1:33 am, prob...@gmail.com wrote:
I am using a message handler class that implements amongst others:

static void message ( std::string aHeader,
std::string aMessage,
int aTimeout = 0,
MessageType aFlag =
MSG_Information );

I then use a set of defines, e.g.:

#define USR_MSG( msg ) MSG::message( "", msg, 0, MSG_User )

The problem is now that I get a compiler error when I write

USR_MSG("The value of x is " << x);

Does anybody have a smart solution for that? I thought about rerouting
std::cout but it doesn't seem to be the best way to me.

Thanks a lot for your help,

Martin.
Write a string format function on your own:
string string_format( char* format, ... ) ;
then wrap vsprintf and provide a formatting routing. You can now do:

USR_MSG( string_format("The value is %d", x) );

Regards,

PQ

May 8 '07 #2
<pr*****@gmail.comwrote in message
news:11*********************@n59g2000hsh.googlegro ups.com...
:I am using a message handler class that implements amongst others:
:
: static void message ( std::string aHeader,
: std::string aMessage,
: int aTimeout = 0,
: MessageType aFlag =
: MSG_Information );
:
: I then use a set of defines, e.g.:
:
: #define USR_MSG( msg ) MSG::message( "", msg, 0, MSG_User )
:
: The problem is now that I get a compiler error when I write
:
: USR_MSG("The value of x is " << x);
:
: Does anybody have a smart solution for that? I thought about rerouting
: std::cout but it doesn't seem to be the best way to me.

Here's a hack-ish macro that uses a stringstream for streaming,
and returns a pointer to a temporary C-string:

template<class C>
inline C& stripConstFromTemporaryRef(C const& r) { return (C&)r; }

#define STRM2CSTR( ss ) \
((::std::ostringstream&) \
(stripConstFromTemporaryRef(::std::ostringstream() ) \
<<ss )).str().c_str()
(NB: the strip... function is needed in case the first streamed
value uses a non-member << function )

Then you would define your macro as:
#define USR_MSG(msg) MSG::message( "", STRM2CSTR(msg), 0, MSG_User )

Of course this adds some run-time overhead in the simple case
where a static string is to be streamed. There should be a way
to use some smart template tricks to optimize-out the simple
case, but I have never bothered looking into this.
I hope this helps,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Brainbench MVP for C++ <http://www.brainbench.com

May 8 '07 #3
On 8 Maj, 07:33, prob...@gmail.com wrote:
I am using a message handler class that implements amongst others:

static void message ( std::string aHeader,
std::string aMessage,
int aTimeout = 0,
MessageType aFlag =
MSG_Information );
You should not pass by value here use std::string const& for aHeader
and aMessage. It also appears that you name the class MSG wwhich is
against the stylistic recommendations of C++ where all-caps is
reserved for macroes. Following these recommendations might save you
lots of trouble later on.
>
I then use a set of defines, e.g.:

#define USR_MSG( msg ) MSG::message( "", msg, 0, MSG_User )
Don't do that: macroes are better avoided. Better is to use a
function, e.g.

inline void user_msg(std::string const& msg)
{
MSG::message( "", msg, 0, MSG_User );
}
(You could have it in your MSG-class if you find that is sensible. (To
me it looks as if you should rather use a namespace).
>
The problem is now that I get a compiler error when I write

USR_MSG("The value of x is " << x);

Does anybody have a smart solution for that? I thought about rerouting
std::cout but it doesn't seem to be the best way to me.
I would probably spend an extra line and use a stringstream here.
Otherwise a macro here could be appropriate:

#define USR_MSG(text_) { std::stringstream s; s << text_;
user_msg(s.str()); }

/Peter

May 8 '07 #4
On May 7, 10:33 pm, prob...@gmail.com wrote:
I am using a message handler class that implements amongst others:

static void message ( std::string aHeader,
std::string aMessage,
int aTimeout = 0,
MessageType aFlag =
MSG_Information );

I then use a set of defines, e.g.:

#define USR_MSG( msg ) MSG::message( "", msg, 0, MSG_User )

The problem is now that I get a compiler error when I write

USR_MSG("The value of x is " << x);

Does anybody have a smart solution for that? I thought about rerouting
std::cout but it doesn't seem to be the best way to me.
The C++ way would be to write an inline function instead of macro:

inline void USR_MSG( const std::string& msg )
{
MSG::message( "", msg, 0, MSG_USER);
}

Now the program may call USR_MSG in a variety of ways, including:

USR_MSG( "This is a message" );

and:

std::string x("5");

USR_MSG( "The value of x is " + x );

Greg

May 8 '07 #5
On May 8, 8:35 am, "Ivan Vecerina"
<_INVALID_use_webfo...@ivan.vecerina.comwrote:
<prob...@gmail.comwrote in message
news:11*********************@n59g2000hsh.googlegro ups.com...
:I am using a message handler class that implements amongst others:
: static void message ( std::string aHeader,
: std::string aMessage,
: int aTimeout = 0,
: MessageType aFlag =
: MSG_Information );
: I then use a set of defines, e.g.:
:
: #define USR_MSG( msg ) MSG::message( "", msg, 0, MSG_User )
:
: The problem is now that I get a compiler error when I write
:
: USR_MSG("The value of x is " << x);
:
: Does anybody have a smart solution for that? I thought about rerouting
: std::cout but it doesn't seem to be the best way to me.

Here's a hack-ish macro that uses a stringstream for streaming,
and returns a pointer to a temporary C-string:
template<class C>
inline C& stripConstFromTemporaryRef(C const& r) { return (C&)r; }
#define STRM2CSTR( ss ) \
((::std::ostringstream&) \
(stripConstFromTemporaryRef(::std::ostringstream() ) \
<<ss )).str().c_str()
(NB: the strip... function is needed in case the first streamed
value uses a non-member << function )
In the case of ostringstream, you can use the even hackier:

(std::ostringstream().flush() << ss)

In such cases, I'll either have message take an std::ostream&
(which it dynamic_casts to std::ostringstream in order to
extract the text), or I'll use the decorator pattern (or
proxy---I'm never really sure which it is), with something like:

class Collector
{
public:
template< typename T >
Collector& operator<<( T const& v )
{
myStream << v ;
return *this ;
}
std::string str()
{
return myStream.str() ;
}
private:
std::ostringstream myStream ;
} ;

(For such a simple case, just using the ostringstream directly,
and calling flush, is probably preferable. In practice, my
"Collector" will different target streams depending on the
level of tracing which has been activated, and such things.)

I've generally wrapped this in a macro anyway, because every
time I've wanted it, I've also wanted automatic insertion of
__FILE__ and __LINE__.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 8 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Heiko Hund | last post: by
3 posts views Thread by Sensei | last post: by
5 posts views Thread by Karl | last post: by
84 posts views Thread by Peter Olcott | last post: by
6 posts views Thread by arnuld | last post: by
2 posts views Thread by Adam Nielsen | last post: by
11 posts views Thread by tech | last post: by
4 posts views Thread by =?ISO-8859-1?Q?Dar=EDo_Griffo?= | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.