Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Reference to temporary

Reply
Thread Tools

Reference to temporary

 
 
Dave
Guest
Posts: n/a
 
      11-05-2003
Hello all,

The code below is not legal (problem with the foo_t initializer list)
because:

"A reference that is not to 'const' cannot be bound to a non-lvalue"

How can I best achieve an effect similar to what this code attempts?

Thanks,
Dave

class bar_t
{
};

class foo_t
{
public:
foo_t(): ref(bar_t()) {}

private:
bar_t &ref;
};

void foo()
{
foo_t a;
}

int main()
{
foo();

return 0;
}



 
Reply With Quote
 
 
 
 
Ron Natalie
Guest
Posts: n/a
 
      11-06-2003

"Dave" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
> Hello all,
>
> The code below is not legal (problem with the foo_t initializer list)
> because:
>
> "A reference that is not to 'const' cannot be bound to a non-lvalue"
>
> How can I best achieve an effect similar to what this code attempts?
>


Use a const reference?


 
Reply With Quote
 
 
 
 
Rob Williscroft
Guest
Posts: n/a
 
      11-06-2003
Dave wrote in news:(E-Mail Removed):

> Hello all,
>
> The code below is not legal (problem with the foo_t initializer list)
> because:
>
> "A reference that is not to 'const' cannot be bound to a non-lvalue"
>
> How can I best achieve an effect similar to what this code attempts?
>
> Thanks,
> Dave
>
> class bar_t
> {
> };
>
> class foo_t
> {
> public:
> foo_t(): ref(bar_t()) {}
>
> private:
> bar_t &ref;
> };


You would have to tell us what is wrong with:

class foo_t
{
public:
foo_t() {}

private:
bar_t ref;
};

I.e. what problem you need to solve.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
Andrey Tarasevich
Guest
Posts: n/a
 
      11-06-2003
Dave wrote:
> ...
> The code below is not legal (problem with the foo_t initializer list)
> because:
>
> "A reference that is not to 'const' cannot be bound to a non-lvalue"
>
> How can I best achieve an effect similar to what this code attempts?
>
>
> class bar_t
> {
> };
>
> class foo_t
> {
> public:
> foo_t(): ref(bar_t()) {}
>
> private:
> bar_t &ref;
> };
>
> void foo()
> {
> foo_t a;
> }
>
> int main()
> {
> foo();
>
> return 0;
> }
> ...


You can't do it this way. It you need a valid reference, which is a
member of some class, you need a valid lvalue object (i.e. a
non-temporary) to initialize it with. The object's lifetime should be at
least as long as the lifetime of the reference.

--
Best regards,
Andrey Tarasevich

 
Reply With Quote
 
Andrey Tarasevich
Guest
Posts: n/a
 
      11-06-2003
Ron Natalie wrote:
>>...
>> The code below is not legal (problem with the foo_t initializer list)
>> because:
>>
>> "A reference that is not to 'const' cannot be bound to a non-lvalue"
>>
>> How can I best achieve an effect similar to what this code attempts?
>>

>
> Use a const reference?
> ...


That will replace one problem with another. The code will compile, but
reference member will only remain valid until the constructor exits.
After that the reference is no longer valid. Something tells me that
that's not what OP intended to achieve.

--
Best regards,
Andrey Tarasevich

 
Reply With Quote
 
Cy Edmunds
Guest
Posts: n/a
 
      11-06-2003
"Dave" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hello all,
>
> The code below is not legal (problem with the foo_t initializer list)
> because:
>
> "A reference that is not to 'const' cannot be bound to a non-lvalue"
>
> How can I best achieve an effect similar to what this code attempts?


[snip]

Just change the reference to an object:

class foo_t
{
private:
bar_t;
};


 
Reply With Quote
 
Dave
Guest
Posts: n/a
 
      11-06-2003
Hello all,

Well, I think I need to elaborate upon my previous post. My simplified
version of things did not provide enough context...

I am maintaining a very poor existing code base (isn't it the bane of all
our existences???). There is a class which contains as a data member an
ofstream object which is used for logging. This object is bound to a log
file upon object construction, so the stream's ready to write to by the time
we start doing any real work. So far so good... Where it gets messy is
that there is also a member function SetStream() to change the stream
dynamically. So, we may log to the initial stream for awhile, and then
decide to start logging to another stream. Seems like a reasonable thing to
want to do. However, SetStream() takes an ofstream parameter by value and
then assigns it to the member ofstream object. There are two problems
here - ofstream has neither a copy constructor nor an assignment operator,
so passing it as a parameter and assigning it are both illegal! This should
have never compiled, but we had a poor compiler (VC++ 6.0) and it was let
through. Now that we've upgraded to a more compliant compiler, the error is
finally getting caught.

So, I need to figure out a way to update this stream data member
dynamically. I have considered changing the data member from ofstream to
ofstream*, but there's a problem. The initial stream (upon object
construction) would have to be dynamically allocated, which means it would
have to be deallocated in the destructor. However, the client code that
uses this class passes non-dynamically allocated ofstream objects when it
calls SetStream(). So, we can start passing pointers rather than the
objects themselves, but the pointer can't be deallocated by the
destructor... I guess I could use a flag to mark whether the pointer points
to the orignal dynamically-allocated object or not, but there's got to be a
more elegant way...

My earlier attempt (in my original post) at trying to find a way to solve
this with reference members was off in la la land because an initializer
list can't initialize a reference member if the class in question has no
copy constructor. If this makes no sense, don't worry about it; there's no
need to go back and look at the original post. It was headed in the wrong
direction...

Thanks again,
Dave


 
Reply With Quote
 
Cy Edmunds
Guest
Posts: n/a
 
      11-06-2003
"Dave" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hello all,
>
> Well, I think I need to elaborate upon my previous post. My simplified
> version of things did not provide enough context...
>
> I am maintaining a very poor existing code base (isn't it the bane of all
> our existences???). There is a class which contains as a data member an
> ofstream object which is used for logging. This object is bound to a log
> file upon object construction, so the stream's ready to write to by the

time
> we start doing any real work. So far so good... Where it gets messy is
> that there is also a member function SetStream() to change the stream
> dynamically. So, we may log to the initial stream for awhile, and then
> decide to start logging to another stream. Seems like a reasonable thing

to
> want to do. However, SetStream() takes an ofstream parameter by value and
> then assigns it to the member ofstream object. There are two problems
> here - ofstream has neither a copy constructor nor an assignment operator,
> so passing it as a parameter and assigning it are both illegal! This

should
> have never compiled, but we had a poor compiler (VC++ 6.0) and it was let
> through. Now that we've upgraded to a more compliant compiler, the error

is
> finally getting caught.
>
> So, I need to figure out a way to update this stream data member
> dynamically. I have considered changing the data member from ofstream to
> ofstream*, but there's a problem. The initial stream (upon object
> construction) would have to be dynamically allocated,


Why?

std:stream *m_pstr;
void SetStream(std:stream &new_stream) {m_pstr = &new_stream;} // pass by
reference and store the address

Of course the life of the stream has to be longer than the life of the
object, but that can't be helped. To use it:

*m_pstr << "whatever";

which means it would
> have to be deallocated in the destructor. However, the client code that
> uses this class passes non-dynamically allocated ofstream objects when it
> calls SetStream(). So, we can start passing pointers rather than the
> objects themselves, but the pointer can't be deallocated by the
> destructor... I guess I could use a flag to mark whether the pointer

points
> to the orignal dynamically-allocated object or not, but there's got to be

a
> more elegant way...
>
> My earlier attempt (in my original post) at trying to find a way to solve
> this with reference members was off in la la land because an initializer
> list can't initialize a reference member if the class in question has no
> copy constructor. If this makes no sense, don't worry about it; there's

no
> need to go back and look at the original post. It was headed in the wrong
> direction...
>
> Thanks again,
> Dave
>




--
Cy
http://home.rochester.rr.com/cyhome/


 
Reply With Quote
 
Dave
Guest
Posts: n/a
 
      11-06-2003

"Cy Edmunds" <(E-Mail Removed)> wrote in message
news:eyvqb.61692$(E-Mail Removed)...
> "Dave" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > Hello all,
> >
> > Well, I think I need to elaborate upon my previous post. My simplified
> > version of things did not provide enough context...
> >
> > I am maintaining a very poor existing code base (isn't it the bane of

all
> > our existences???). There is a class which contains as a data member an
> > ofstream object which is used for logging. This object is bound to a

log
> > file upon object construction, so the stream's ready to write to by the

> time
> > we start doing any real work. So far so good... Where it gets messy is
> > that there is also a member function SetStream() to change the stream
> > dynamically. So, we may log to the initial stream for awhile, and then
> > decide to start logging to another stream. Seems like a reasonable

thing
> to
> > want to do. However, SetStream() takes an ofstream parameter by value

and
> > then assigns it to the member ofstream object. There are two problems
> > here - ofstream has neither a copy constructor nor an assignment

operator,
> > so passing it as a parameter and assigning it are both illegal! This

> should
> > have never compiled, but we had a poor compiler (VC++ 6.0) and it was

let
> > through. Now that we've upgraded to a more compliant compiler, the

error
> is
> > finally getting caught.
> >
> > So, I need to figure out a way to update this stream data member
> > dynamically. I have considered changing the data member from ofstream

to
> > ofstream*, but there's a problem. The initial stream (upon object
> > construction) would have to be dynamically allocated,

>
> Why?


What other option do I have for getting an initial per-object stream to set
the member pointer to point at?

>
> std:stream *m_pstr;
> void SetStream(std:stream &new_stream) {m_pstr = &new_stream;} // pass

by
> reference and store the address
>
> Of course the life of the stream has to be longer than the life of the
> object, but that can't be helped. To use it:
>
> *m_pstr << "whatever";
>
> which means it would
> > have to be deallocated in the destructor. However, the client code that
> > uses this class passes non-dynamically allocated ofstream objects when

it
> > calls SetStream(). So, we can start passing pointers rather than the
> > objects themselves, but the pointer can't be deallocated by the
> > destructor... I guess I could use a flag to mark whether the pointer

> points
> > to the orignal dynamically-allocated object or not, but there's got to

be
> a
> > more elegant way...
> >
> > My earlier attempt (in my original post) at trying to find a way to

solve
> > this with reference members was off in la la land because an initializer
> > list can't initialize a reference member if the class in question has no
> > copy constructor. If this makes no sense, don't worry about it; there's

> no
> > need to go back and look at the original post. It was headed in the

wrong
> > direction...
> >
> > Thanks again,
> > Dave
> >

>
>
>
> --
> Cy
> http://home.rochester.rr.com/cyhome/
>
>



 
Reply With Quote
 
Cy Edmunds
Guest
Posts: n/a
 
      11-06-2003
"Dave" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>
> "Cy Edmunds" <(E-Mail Removed)> wrote in message
> news:eyvqb.61692$(E-Mail Removed)...
> > "Dave" <(E-Mail Removed)> wrote in message
> > news:(E-Mail Removed)...
> > > Hello all,
> > >
> > > Well, I think I need to elaborate upon my previous post. My

simplified
> > > version of things did not provide enough context...
> > >
> > > I am maintaining a very poor existing code base (isn't it the bane of

> all
> > > our existences???). There is a class which contains as a data member

an
> > > ofstream object which is used for logging. This object is bound to a

> log
> > > file upon object construction, so the stream's ready to write to by

the
> > time
> > > we start doing any real work. So far so good... Where it gets messy

is
> > > that there is also a member function SetStream() to change the stream
> > > dynamically. So, we may log to the initial stream for awhile, and

then
> > > decide to start logging to another stream. Seems like a reasonable

> thing
> > to
> > > want to do. However, SetStream() takes an ofstream parameter by value

> and
> > > then assigns it to the member ofstream object. There are two problems
> > > here - ofstream has neither a copy constructor nor an assignment

> operator,
> > > so passing it as a parameter and assigning it are both illegal! This

> > should
> > > have never compiled, but we had a poor compiler (VC++ 6.0) and it was

> let
> > > through. Now that we've upgraded to a more compliant compiler, the

> error
> > is
> > > finally getting caught.
> > >
> > > So, I need to figure out a way to update this stream data member
> > > dynamically. I have considered changing the data member from ofstream

> to
> > > ofstream*, but there's a problem. The initial stream (upon object
> > > construction) would have to be dynamically allocated,

> >
> > Why?

>
> What other option do I have for getting an initial per-object stream to

set
> the member pointer to point at?
>



I showed you but you snipped that part out! LOL

Pass a reference in the argument list and then take its address. I've done
this before and it works fine.

Maybe my previous thing was a little cryptic. Here is a more explicit
example:

class Funky
{
private:
std:stream *m_pstr;

public:
Funky(std:stream &ostr) : m_pstr(&ostr) {} // note & operator

void SetStream(std:stream &ostr) {m_pstr = &ostr;} // & operator again
};

--
Cy
http://home.rochester.rr.com/cyhome/


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
anonymous array of strings // ("taking address of temporary"- how long is temporary valid?) anon.asdf@gmail.com C++ 7 02-12-2008 10:58 AM
Reference to temporary Andriy Shnyr C++ 1 02-25-2004 07:58 PM
A reference to non-const to be bound to a temporary object John Ky C++ 9 02-23-2004 12:53 AM
The temporary vs non-const reference love story =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunion?= C++ 13 11-06-2003 02:52 PM
iterator / returning reference to local temporary Alexander Stippler C++ 2 07-04-2003 04:40 PM



Advertisments