Reference parameters and anonymous objects | | |
I have a bit of a problem with an overloaded operator that I'm writing that
I have distilled down to an example in the code below. Essentially, I have
an operator function (+=) that takes a reference parameter of class Poly.
If I use it with a named object (of type Poly), as in:
P1+=P4;
where P1 and P4 are both local variables of the class type, it works fine.
If I try to use an anonymous object on the right side, then I get an error
such as:
error: no match for `Poly& += Poly' operator
This wouldn't be much of a problem if another overloaded operator (+) didn't
return an anonymous copy of a Poly object, so if I write:
P1 += (P2 + P3);
then the RHS is an anonymous Poly object, and the += call won't compile.
This also happens with an overloaded << operator that takes a Poly & if I
try:
cout << (P2 + P3);
I can't find much written about function reference parameters and anonymous
objects. It makes some sense that forming a reference to an object that has
no other name might not be allowed, but I can't find anywhere that says
this. Note also, that this code compiles and works fine in MS Visual C++,
but won't compile on any version of g++ on Linux or the Mac that I've tried.
Any insights on this?
Thanks.
Mark Brandyberry
_________________________________________Poly.h
#include <iostream>
using namespace std;
class Poly {
private:
int i, j, k;
public:
Poly() {i=j=k=0;}
Poly(int x, int y, int z) {i=x;j=y;k=z;}
Poly operator+(Poly &);
void operator+=(Poly &);
friend ostream & operator<<(ostream &, Poly &);
};
________________________________________Poly.cpp
#include "Poly.h"
Poly Poly::operator+(Poly & p) {
Poly t(0,0,0);
t.i=p.i+i;
t.j=p.j+j;
t.k=p.k+k;
return(t);
}
void Poly::operator+=(Poly & p){
i+=p.i; j+=p.j; k+=p.k;
}
ostream & operator<<(ostream & strm, Poly & p) {
strm << "Poly i, j, k = " << p.i << "," << p.j << "," << p.k <<
endl;
return(strm);
}
________________________________________main.cpp
#include "Poly.h"
int main() {
Poly P1, P2(1,2,3), P3(4,5,6), P4;
cout << P1 << P2 << P3;
P1 = P2 + P3;
cout << P1;
P1=P4;
P1+=P2;
cout << P1;
P1=P4;
//the following line will not compile
P1+=(P2+P3);
//the following line will not compile
P1+=Poly(5,10,20);
cout << P1;
P1=P4;
//the following line will not compile
cout << (P2+P3);
return(0);
} | | | | re: Reference parameters and anonymous objects
"Mark Brandyberry" <mdbrandy@uiuc.edu> wrote in message
news:d18d5l$627$1@news.ks.uiuc.edu[color=blue]
> I have a bit of a problem with an overloaded operator that I'm
> writing that I have distilled down to an example in the code below.
> Essentially, I have an operator function (+=) that takes a reference
> parameter of class Poly. If I use it with a named object (of type
> Poly), as in:
> P1+=P4;
>
> where P1 and P4 are both local variables of the class type, it works
> fine. If I try to use an anonymous object on the right side, then I
> get an error such as:
>
> error: no match for `Poly& += Poly' operator
>
> This wouldn't be much of a problem if another overloaded operator (+)
> didn't return an anonymous copy of a Poly object, so if I write:
>
> P1 += (P2 + P3);
>
> then the RHS is an anonymous Poly object, and the += call won't
> compile. This also happens with an overloaded << operator that takes
> a Poly & if I try:
>
> cout << (P2 + P3);
>
> I can't find much written about function reference parameters and
> anonymous objects. It makes some sense that forming a reference to
> an object that has no other name might not be allowed, but I can't
> find anywhere that says this. Note also, that this code compiles and
> works fine in MS Visual C++, but won't compile on any version of g++
> on Linux or the Mac that I've tried. Any insights on this?
>
> Thanks.
>
> Mark Brandyberry
>
>
> _________________________________________Poly.h
> #include <iostream>
> using namespace std;
>
> class Poly {
> private:
> int i, j, k;
> public:
> Poly() {i=j=k=0;}
> Poly(int x, int y, int z) {i=x;j=y;k=z;}
> Poly operator+(Poly &);
> void operator+=(Poly &);
> friend ostream & operator<<(ostream &, Poly &);
> };
> ________________________________________Poly.cpp
> #include "Poly.h"
>
> Poly Poly::operator+(Poly & p) {
> Poly t(0,0,0);
> t.i=p.i+i;
> t.j=p.j+j;
> t.k=p.k+k;
> return(t);
> }
>
> void Poly::operator+=(Poly & p){
> i+=p.i; j+=p.j; k+=p.k;
> }
>
> ostream & operator<<(ostream & strm, Poly & p) {
> strm << "Poly i, j, k = " << p.i << "," << p.j << "," << p.k <<
> endl;
> return(strm);
> }
> ________________________________________main.cpp
> #include "Poly.h"
>
> int main() {
> Poly P1, P2(1,2,3), P3(4,5,6), P4;
> cout << P1 << P2 << P3;
> P1 = P2 + P3;
> cout << P1;
> P1=P4;
> P1+=P2;
> cout << P1;
> P1=P4;
> //the following line will not compile
> P1+=(P2+P3);
> //the following line will not compile
> P1+=Poly(5,10,20);
> cout << P1;
> P1=P4;
> //the following line will not compile
> cout << (P2+P3);
> return(0);
> }[/color]
What you call "anonymous objects" are temporaries. You cannot supply
temporaries as arguments to functions/operators that take references to
objects as arguments. Your problems will be solved if you simply make the
functions/operators take references to *const* objects as arguments, e.g.,
void operator+=(const Poly &);
void Poly::operator+=(const Poly & p)
{
i+=p.i; j+=p.j; k+=p.k;
}
--
John Carson | | | | re: Reference parameters and anonymous objects
The function signature for void Poly::operator+=(Poly & p) should be
Poly &Poly::operator+=(Poly & p); | | | | re: Reference parameters and anonymous objects
Ignore my last post I am dreaming. | | | | re: Reference parameters and anonymous objects
"John Carson" <jcarson_n_o_sp_am_@netspace.net.au> wrote in message
news:d18ua8$1nq0$1@otis.netspace.net.au...[color=blue]
> "Mark Brandyberry" <mdbrandy@uiuc.edu> wrote in message
> news:d18d5l$627$1@news.ks.uiuc.edu[color=green]
>> I have a bit of a problem with an overloaded operator that I'm
>> writing that I have distilled down to an example in the code below.
>> Essentially, I have an operator function (+=) that takes a reference
>> parameter of class Poly. If I use it with a named object (of type
>> Poly), as in:
>> P1+=P4;
>>[/color][/color]
<snip>
[color=blue][color=green]
>>
>> I can't find much written about function reference parameters and
>> anonymous objects. It makes some sense that forming a reference to
>> an object that has no other name might not be allowed, but I can't
>> find anywhere that says this. Note also, that this code compiles and
>> works fine in MS Visual C++, but won't compile on any version of g++
>> on Linux or the Mac that I've tried. Any insights on this?
>>
>> Thanks.
>>
>> Mark Brandyberry[/color][/color]
<snip>
[color=blue]
> What you call "anonymous objects" are temporaries. You cannot supply
> temporaries as arguments to functions/operators that take references to
> objects as arguments. Your problems will be solved if you simply make the
> functions/operators take references to *const* objects as arguments, e.g.,
>
> void operator+=(const Poly &);
>
> void Poly::operator+=(const Poly & p)
> {
> i+=p.i; j+=p.j; k+=p.k;
> }
>
>
> --
> John Carson
>[/color]
John,
Yes, I knew that what some authors call anonymous objects are temporary,
which is why they're useful. Your response does fix the problem, and I
should have thought of it. I was trying to keep the example code as simple
as possible, so I didn't add the const qualifier. I think this is the first
place I've seen where the const qualifier is actually required, and not just
a good idea. I suppose it does make sense, since now the compiler can be
sure that you aren't going to try to change the reference, and thus change
the anonymous (temporary) object to no good purpose (since it won't be
available when you return from the function anyway). I assume VC++ is just
allowing incorrect code to go through? Or is this really part of the
defined C++ standard? I don't have any experience actually looking at the
standard...
Thanks!
Mark | | | | re: Reference parameters and anonymous objects
"Mark Brandyberry" <mdbrandy@uiuc.edu> wrote in message
news:d19ho6$f8f$1@news.ks.uiuc.edu[color=blue]
>
> Yes, I knew that what some authors call anonymous objects are
> temporary, which is why they're useful. Your response does fix the
> problem, and I should have thought of it. I was trying to keep the
> example code as simple as possible, so I didn't add the const
> qualifier. I think this is the first place I've seen where the const
> qualifier is actually required, and not just a good idea. I suppose
> it does make sense, since now the compiler can be sure that you
> aren't going to try to change the reference, and thus change the
> anonymous (temporary) object to no good purpose (since it won't be
> available when you return from the function anyway). I assume VC++
> is just allowing incorrect code to go through? Or is this really
> part of the defined C++ standard? I don't have any experience
> actually looking at the standard...
>
> Thanks!
>
> Mark[/color]
The const is required by the C++ standard. VC++ doesn't require it,
presumably for some backwards compatibility reason.
--
John Carson | | | | re: Reference parameters and anonymous objects
mark, take a look at "expression templates". CUJ had 1 or more articles
some time ago.
benedetto
Mark Brandyberry wrote:[color=blue]
> "John Carson" <jcarson_n_o_sp_am_@netspace.net.au> wrote in message
> news:d18ua8$1nq0$1@otis.netspace.net.au...[color=green]
> > "Mark Brandyberry" <mdbrandy@uiuc.edu> wrote in message
> > news:d18d5l$627$1@news.ks.uiuc.edu[color=darkred]
> >> I have a bit of a problem with an overloaded operator that I'm
> >> writing that I have distilled down to an example in the code[/color][/color][/color]
below.[color=blue][color=green][color=darkred]
> >> Essentially, I have an operator function (+=) that takes a[/color][/color][/color]
reference[color=blue][color=green][color=darkred]
> >> parameter of class Poly. If I use it with a named object (of type
> >> Poly), as in:
> >> P1+=P4;
> >>[/color][/color]
>
> <snip>
>[color=green][color=darkred]
> >>
> >> I can't find much written about function reference parameters and
> >> anonymous objects. It makes some sense that forming a reference[/color][/color][/color]
to[color=blue][color=green][color=darkred]
> >> an object that has no other name might not be allowed, but I can't
> >> find anywhere that says this. Note also, that this code compiles[/color][/color][/color]
and[color=blue][color=green][color=darkred]
> >> works fine in MS Visual C++, but won't compile on any version of[/color][/color][/color]
g++[color=blue][color=green][color=darkred]
> >> on Linux or the Mac that I've tried. Any insights on this?
> >>
> >> Thanks.
> >>
> >> Mark Brandyberry[/color][/color]
>
> <snip>
>[color=green]
> > What you call "anonymous objects" are temporaries. You cannot[/color][/color]
supply[color=blue][color=green]
> > temporaries as arguments to functions/operators that take[/color][/color]
references to[color=blue][color=green]
> > objects as arguments. Your problems will be solved if you simply[/color][/color]
make the[color=blue][color=green]
> > functions/operators take references to *const* objects as[/color][/color]
arguments, e.g.,[color=blue][color=green]
> >
> > void operator+=(const Poly &);
> >
> > void Poly::operator+=(const Poly & p)
> > {
> > i+=p.i; j+=p.j; k+=p.k;
> > }
> >
> >
> > --
> > John Carson
> >[/color]
>
> John,
>
> Yes, I knew that what some authors call anonymous objects are[/color]
temporary,[color=blue]
> which is why they're useful. Your response does fix the problem, and[/color]
I[color=blue]
> should have thought of it. I was trying to keep the example code as[/color]
simple[color=blue]
> as possible, so I didn't add the const qualifier. I think this is[/color]
the first[color=blue]
> place I've seen where the const qualifier is actually required, and[/color]
not just[color=blue]
> a good idea. I suppose it does make sense, since now the compiler[/color]
can be[color=blue]
> sure that you aren't going to try to change the reference, and thus[/color]
change[color=blue]
> the anonymous (temporary) object to no good purpose (since it won't[/color]
be[color=blue]
> available when you return from the function anyway). I assume VC++[/color]
is just[color=blue]
> allowing incorrect code to go through? Or is this really part of the[/color]
[color=blue]
> defined C++ standard? I don't have any experience actually looking[/color]
at the[color=blue]
> standard...
>
> Thanks!
>
> Mark[/color] |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,501 network members.
|