C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

comma overloading

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Fabio
Guest





PostPosted: Tue Aug 10, 2004 7:07 pm    Post subject: comma overloading Reply with quote



I try this code with g++3.3.1, vc7.1 and intel7.1.

#include <iostream>
#include <vector>
using namespace std;

class AClass {};

vector<AClass> operator , (AClass a, AClass b)
{
cout << "AClass,AClass" << endl;
vector ret.push_back(a);
ret.push_back(b);
return ret;
}

vector<AClass>& operator , (vector<AClass>& vect, AClass a)
{
cout << "vect vect.push_back(a);
return vect;
}

int main()
{
AClass(),AClass(),AClass();
return 0;
}

I've got different behaviours.
With g++ i got a strange behavior: it calls just
"operator,(AClass,AClass)".
The others seems to do the right choice, calling
"operator,(AClass,AClass)"
and then "operator,(vector Which one is right?!
Avoiding references g++ works well (vector<AClass>
operator,(vector<AClass> vect, AClass a))
....but...
Thanks.
--Fabio

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Victor Bazarov
Guest





PostPosted: Wed Aug 11, 2004 10:45 am    Post subject: Re: comma overloading Reply with quote



Fabio wrote:
Quote:
I try this code with g++3.3.1, vc7.1 and intel7.1.

#include <iostream
#include using namespace std;

class AClass {};

vector {
cout << "AClass,AClass" << endl;
vector ret.push_back(a);
ret.push_back(b);
return ret;
}

vector<AClass>& operator , (vector<AClass>& vect, AClass a)
{
cout << "vect vect.push_back(a);
return vect;
}

int main()
{
AClass(),AClass(),AClass();
return 0;
}

I've got different behaviours.
With g++ i got a strange behavior: it calls just
"operator,(AClass,AClass)".
The others seems to do the right choice, calling
"operator,(AClass,AClass)"
and then "operator,(vector Which one is right?!

The first operator comma returns a temporary. The second operator comma
takes the vector by a non-const ref, which is not supposed to be bound
to a temporary. So, the alternative is to use the built-in operator comma
for the second expression. So, I believe g++ gets it right.

Try disabling language extensions in VC++, you'll get

test.cpp(25) : warning C4913: user defined binary operator ',' exists but
no overload could convert all operands, default built-in binary operator
',' used

Quote:
Avoiding references g++ works well (vector<AClass
operator,(vector ...but...

As it should. Since no non-const reference is involved, the temporary
is copied into another temporary and the overloaded operator is called.

Victor

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andrea Griffini
Guest





PostPosted: Wed Aug 11, 2004 10:50 am    Post subject: Re: comma overloading Reply with quote



On 10 Aug 2004 15:07:47 -0400, [email]fabioppp_it (AT) yahoo (DOT) it[/email] (Fabio) wrote:

Quote:
Which one is right?!
Avoiding references g++ works well (vector<AClass
operator,(vector ...but...
Thanks.

I think that g++ is right; the vector that is the
result of the first comma is a temporary and so
cannot be bound to a non-const reference.
Given that the signature for the second comma
operator you defined requires a non-const
reference that operator is ignored (the signature
simply doesn't match), and the default comma
operator is invoked instead.

To get it working with references may be you can
change the signature to accept a const reference
and then cast away const-ness...

vector<AClass>& operator , (const vector<AClass>& vect, AClass a)
{
cout << "vect vector(vect);
ncvect.push_back(a);
return ncvect;
}

HTH
Andrea

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Vladimír Marko
Guest





PostPosted: Wed Aug 11, 2004 7:41 pm    Post subject: Re: comma overloading Reply with quote

"Fabio" <fabioppp_it (AT) yahoo (DOT) it> wrote

Quote:
I try this code with g++3.3.1, vc7.1 and intel7.1.

#include <iostream
#include using namespace std;

class AClass {};

vector {
cout << "AClass,AClass" << endl;
vector ret.push_back(a);
ret.push_back(b);
return ret;
}

vector<AClass>& operator , (vector<AClass>& vect, AClass a)
{
cout << "vect vect.push_back(a);
return vect;
}

int main()


AClass(),AClass(),AClass();
return 0;
}

I've got different behaviours.
With g++ i got a strange behavior: it calls just
"operator,(AClass,AClass)".
The others seems to do the right choice, calling
"operator,(AClass,AClass)"
and then "operator,(vector Which one is right?!
Avoiding references g++ works well (vector<AClass
operator,(vector ...but...
Thanks.
--Fabio

You've got an unnamed temporary that's not
supposed to bind to vector<AClass>&, right?
Thus, the compiler should choose the implicit
operator , . IMHO g++ is right.

Btw. if you ever read the move proposal,
I think the implicit operator , should read as
template <class A,class B>
B& operator , (A&&,B& b) { return b; }
template <class A,class B>
B&& operator , (A&&,B&& b) { return b; }
The latter overload with A=vector<AClass>
and B=AClass is the only match in your snippet.

Regards,
Vladimir Marko




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Wed Aug 11, 2004 7:41 pm    Post subject: Re: comma overloading Reply with quote

[email]fabioppp_it (AT) yahoo (DOT) it[/email] (Fabio) wrote in message
news:<61b68bb2.0408092355.447a94f (AT) posting (DOT) google.com>...

Quote:
I try this code with g++3.3.1, vc7.1 and intel7.1.

#include <iostream
#include using namespace std;

class AClass {};

vector {
cout << "AClass,AClass" << endl;
vector ret.push_back(a);
ret.push_back(b);
return ret;
}

vector<AClass>& operator , (vector<AClass>& vect, AClass a)
{
cout << "vect vect.push_back(a);
return vect;
}

int main()
{
AClass(),AClass(),AClass();
return 0;
}

I've got different behaviours.
With g++ i got a strange behavior: it calls just
"operator,(AClass,AClass)".
The others seems to do the right choice, calling
"operator,(AClass,AClass)"
and then "operator,(vector Which one is right?!

None of them. The code shouldn't compile. Basically, in the first line
of main, there is no way that the operator, with a vector can be legally
called. It's first parameter is a non-const reference, and cannot be
bound to a temporary. And since, in the first line, you only have
temporaries...

This is a change with regards to the original language, although as
changes go, it is a very old change -- the ARM already documented it as
illegal, back in 1990 (I think). Never the less, a lot of compilers
apparently don't enforce the rule. And obviously, if the vector
operator, can be called, then the behavior of VC 7.1 and Intel 7.1 is
appropriate.

If the vector version cannot be called, however, I don't see how the
other operator, can possibly be called. There is no conversion that I
can see which would allow passing the vector<AClass> returned by the
first operator, as an AClass.

Note that there are in fact three sets of rules. Suppose that instead
of vector<AClass>, you returned some class which could convert
implicitly to an AClass. We then have:

- The original rules, which are apparently still implemented by VC++
and Intel (although the construct was banned by the ARM, and CFront
3.0.1 gave a warning as early as 1991). The second operator, is
called.

- The rules in the ARM: the temporary cannot bind to the reference,
but this fact did not exclude the function from the overload set.
The result is that overload resolution would chose the second
operator, and the compiler would then reject the call as illegal.

- The rules in the standard (I think -- I'm too lazy to look them up
and verify): because the temporary cannot bind to the first
parameter, the second operator, is not viable, and is excluded from
the overload set. The result is that only the first operator, is
considered, and it is called (using the implicit conversion).

Quote:
Avoiding references g++ works well (vector<AClass
operator,(vector ...but...

That's because the copy constructor for vector, used to pass the
parameter by copy, takes a const reference, so the temporary can bind to
it.

An obvious solution is to use some sort of simple handle which manages a
vector, rather than using vector directly.

And an even better solution would probably be to avoid overloading
operator, in the first place. I can't think of any case where the
results are even vaguely readable.

--
James Kanze GABI Software http://www.gabi-soft.fr
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

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Maeder
Guest





PostPosted: Wed Aug 11, 2004 7:46 pm    Post subject: Re: comma overloading Reply with quote

[email]fabioppp_it (AT) yahoo (DOT) it[/email] (Fabio) writes:

Quote:
I try this code with g++3.3.1, vc7.1 and intel7.1.

#include <iostream
#include using namespace std;

class AClass {};

vector {
cout << "AClass,AClass" << endl;
vector ret.push_back(a);
ret.push_back(b);
return ret;
}

vector<AClass>& operator , (vector<AClass>& vect, AClass a)
{
cout << "vect vect.push_back(a);
return vect;
}

int main()
{
AClass(),AClass(),AClass();
return 0;
}

I've got different behaviours.
With g++ i got a strange behavior: it calls just
"operator,(AClass,AClass)".
The others seems to do the right choice, calling
"operator,(AClass,AClass)"
and then "operator,(vector Which one is right?!

g++

Evaluating AClass(),AClass() gives you a temporary vector<AClass> object.
References to non-const can't be bound to temporary objects, so

vector<AClass>& operator , (vector<AClass>& vect, AClass a)

is not considered when the second , is evaluated.


Quote:
Avoiding references g++ works well (vector<AClass
operator,(vector

as should changing the second overload to

vector<AClass>& operator , (vector<AClass> const & vect, AClass a)

, but this would disallow the push_back(), of course.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Maxim Yegorushkin
Guest





PostPosted: Wed Aug 11, 2004 7:48 pm    Post subject: Re: comma overloading Reply with quote

Fabio <fabioppp_it (AT) yahoo (DOT) it> wrote:

Quote:
I try this code with g++3.3.1, vc7.1 and intel7.1.

#include <iostream
#include using namespace std;

class AClass {};

vector

Note that the function returns an r-value (actually, all functions return r-values, unless they return a reference)

[]

Quote:
vector<AClass>& operator , (vector<AClass>& vect, AClass a)

Also note, that vector<AClass>& is a non-const reference, that can not be bound to r-value (a temprorary).

[]

Quote:

int main()
{
AClass(),AClass(),AClass();
return 0;
}

I've got different behaviours.
With g++ i got a strange behavior: it calls just
"operator,(AClass,AClass)".

g++ is right. operator,(AClass,AClass) yields an r-value which can not be bound to vector<AClass>&.

Quote:
The others seems to do the right choice, calling
"operator,(AClass,AClass)"
and then "operator,(vector<AClass>& vect, AClass a)".

MSVC's are wrong. You can disable language extensions in MS compilers and then you'll get the behaviour of g++ (and won't be able to compile with MS headers).

Quote:
Which one is right?!
Avoiding references g++ works well (vector<AClass
operator,(vector

Or you can take a const reference, that is vector<AClass> const&

--
Maxim Yegorushkin

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Maeder
Guest





PostPosted: Fri Aug 13, 2004 10:52 am    Post subject: Re: comma overloading Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] writes:

Quote:
None of them. The code shouldn't compile. Basically, in the first line
of main, there is no way that the operator, with a vector can be legally
called. It's first parameter is a non-const reference, and cannot be
bound to a temporary. And since, in the first line, you only have
temporaries...

Is there a problem with calling the built-in comma operator in this case?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Aug 16, 2004 7:44 pm    Post subject: Re: comma overloading Reply with quote

Thomas Maeder <maeder (AT) glue (DOT) ch> wrote

Quote:
kanze (AT) gabi-soft (DOT) fr writes:

None of them. The code shouldn't compile. Basically, in the first
line of main, there is no way that the operator, with a vector can
be legally called. It's first parameter is a non-const reference,
and cannot be bound to a temporary. And since, in the first line,
you only have temporaries...

Is there a problem with calling the built-in comma operator in this
case?

Only if the author of the compiler is as careless as I am, and forgets
about it once he starts considering user defined operators:-). My
mistake.

In many ways, this is a very strong argument against overloading the
comma operator. Get something wrong, and you don't get a compiler
error. You just get what the normal reader would have expected to begin
with, if you hadn't tried to be clever.

--
James Kanze GABI Software http://www.gabi-soft.fr
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

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.