James Kanze
10/1/2008 9:49:00 AM
On Oct 1, 7:44 am, Thomas Lenz <len...@gmx.de> wrote:
> The code below should allow to use a comma instead of << with
> ostreams and include a space between two operands when comma
> is used. e.g.
> cout << "hello", "world", endl;
> should print the line "hello world".
Why? Have you overloaded the comma operator to do this? If so,
it's obfuscation; the classical idiom is:
std::cout << "hello" << ' ' << "world" << std::endl ;
And when there's a classical idiom, overloading operators to use
a different syntax is obfuscation in the first degree.
> #include <iostream>
> using namespace std;
> inline std::ostream& operator,(std::ostream& rhs_, std::ostream& (* arg_
> (std::ostream&))
> { return (rhs_ << arg_);}
> template<class T> std::ostream& operator,(std::ostream& rhs_, T arg_) {
> return (rhs_ << ' ' << arg_); }
> int main()
> { cout << "hello", "world", endl;
> }
> When I compile with the Weffc++ option, i get the warnings:
> junk.cpp:5: Warning: user-defined »std::ostream& operator,(std::ostream&,
> std::ostream& (*)(std::ostream&))« always evaluates both arguments
> junk.cpp:9: Warning: user-defined »std::ostream& operator,(std::ostream&,
> T)« always evaluates both arguments
> Why?
Well, the message is confusing. Of course, the operator, always
evaluates both arguments. The message looks more like it was
meant for && and || (where user defined operators always
evaluate both arguments, but the built-in operators
short-circuit). But overloading the comma operator like this is
*not* a good idea. Overloading the comma operator in general is
not a good idea (and is forbidden in most coding guidelines).
> I mean, of course the operator evaluates both arguments,
> that's what they are for. BTW the code works fine; I'm just
> confused by these warnings. I didn't find anything in the
> effective c++ books that could throw some light on this. Can
> you?
Well, if the message had said something about the operator not
introducing a sequence point (when the built-in operator does),
it would make sense. Or simply if it said that this could
silently change the meaning of working code.
One of the rare legitimate uses I can think of the comma
operator is for conditionally inserting debugging output, in
conjunction with macros. Something like:
#ifdef ACTIVATE_DEBUGGING
#define TRACE( x ) std::cerr << x
#else
#define TRACE( x ) (void)0
#endif
class C
{
public:
C( int i ) : myValue( TRACE( i ), i ) {}
// ...
} ;
If your operator is defined before this header is included,
you're going to get some very surprising results when tracing is
turned on.
--
James Kanze (GABI Software) email:james.kanze@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