temporary bounded to reference param in function...

W

werasm

Hi all,

I just want to clarify this example:

#include <memory>

struct X
{
virtual std::auto_ptr<X> clone() const;
//etc...
};
struct Y
{
virtual std::auto_ptr<Y> clone() const;
//etc...
};

template <class T>
class Opt
{
public:
Opt( const T& ref ): p_( &ref ){ }
std::auto_ptr<T> clone( T* ) const
{ return p_->clone(); }
private:
const T* p_;
};

struct OptXY : Opt<X>, Opt<Y>
{
OptXY( const X& x, const Y& y )
: Opt<X>( x ), Opt<Y>( y ){ }
};

void foo( const Opt<X>&, const Opt<Y>&, const OptXY& );

int main()
{
foo(
Opt<X>( X() ),
Opt<Y>( Y() ),
OptXY( X(), Y() ) );
}

If I understand 12.2.5 correctly, then all the temporaries will be
destroyed at the end of the body of foo, the order being opposite
to the order of creation (which is undetermined). It would then
be safe to say that they are usable (and the clone is safe)
anywhere within the body of foo. Is this right?

Regards,

Werner
 
V

Victor Bazarov

werasm said:
I just want to clarify this example:

#include <memory>

struct X
{
virtual std::auto_ptr<X> clone() const;
//etc...
};
struct Y
{
virtual std::auto_ptr<Y> clone() const;
//etc...
};

template <class T>
class Opt
{
public:
Opt( const T& ref ): p_( &ref ){ }
std::auto_ptr<T> clone( T* ) const
{ return p_->clone(); }
private:
const T* p_;
};

struct OptXY : Opt<X>, Opt<Y>
{
OptXY( const X& x, const Y& y )
: Opt<X>( x ), Opt<Y>( y ){ }
};

void foo( const Opt<X>&, const Opt<Y>&, const OptXY& );

int main()
{
foo(
Opt<X>( X() ),
Opt<Y>( Y() ),
OptXY( X(), Y() ) );
}

If I understand 12.2.5 correctly, then all the temporaries will be
destroyed at the end of the body of foo, the order being opposite
to the order of creation (which is undetermined). It would then
be safe to say that they are usable (and the clone is safe)
anywhere within the body of foo. Is this right?

I went back and forth a couple of times on this one...

Yes, it's right. The X() and Y() temporaries survive until the full
expression in which they are used is evaluated, which includes the
call to 'foo'. The pointers Opt<X> and Opt<Y> retain will remain
valid until the temporaries to which they point are destroyed. If
you don't try to hold onto the 'p_' members of the temporaries, you
should be OK. So, it all comes down to what 'clone' does. If it
does what 'clone' usually does, create a dynamic object which is
a copy of the one for which 'clone' is called, then all is well.

V
 
W

werasm

Yes, it's right. The X() and Y() temporaries survive until the full
expression in which they are used is evaluated, which includes the
call to 'foo'.

I wrote some code where I had various constructors, using various
types of "Options" objects that contained constant references
(of temporaries) to be cloned, depending on the options, and
I wanted to make sure the constant reference's lifetime exceeded
that of the options object's constructors. I rediscovered the
code and suddenly became a little paranoiac, but in asking the
question I almost concluded that the answer had to be as you
mentioned (if I understood it correctly).

Thanks,

Werner
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top