 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Fabio Guest
|
Posted: Tue Aug 10, 2004 7:07 pm Post subject: comma overloading |
|
|
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
|
Posted: Wed Aug 11, 2004 10:45 am Post subject: Re: comma overloading |
|
|
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
|
Posted: Wed Aug 11, 2004 10:50 am Post subject: Re: comma overloading |
|
|
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
|
Posted: Wed Aug 11, 2004 7:41 pm Post subject: Re: comma overloading |
|
|
"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
|
Posted: Wed Aug 11, 2004 7:41 pm Post subject: Re: comma overloading |
|
|
[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
|
Posted: Wed Aug 11, 2004 7:46 pm Post subject: Re: comma overloading |
|
|
[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
|
Posted: Wed Aug 11, 2004 7:48 pm Post subject: Re: comma overloading |
|
|
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
|
Posted: Fri Aug 13, 2004 10:52 am Post subject: Re: comma overloading |
|
|
[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
|
Posted: Mon Aug 16, 2004 7:44 pm Post subject: Re: comma overloading |
|
|
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 |
|
 |
|
|
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
|
|