Question

Greetings, everyone!

I have a class that receives a pointer to a "circle" (for example) and then adjusts its attributes via some "chaining" methods. Something like this:

class CCircleSetter
{
public:
   explicit CCircleSetter( CCirclePtr circle ) : m_circle(circle)
   {
   }

   CCircleSetter & Radius( int radius )
   {
       if (m_circle) m_circle->SetAttribute( "radius", radius );
       return *this;
   }
   CCircleSetter & Center( CPoint center )
   {
       if (m_circle) m_circle->SetAttribute( "center", center );
       return *this;
   }

   operator bool() const
   {
      return ( m_circle != NULL );
   }

private:
   CCirclePtr m_circle;
};

Now I wonder whether this code is legal or not:

if ( CCircleSetter(myCircle).Radius(10).Center(myPoint) ) 
{ ... }

On the one hand, I think that temporary object, created inside "if" expression, will live until the end of this expression. So, the calls to "Radius" and "Center" are legal. But on the other hand, it is an undefined behavior to use references to temporary variables and it seems to me that I am doing exactly this kind of thing - using (*this), where "this" is a temporary. It gives me some doubts, so, please, clarify. Thanks!

Was it helpful?

Solution

No, that's fine in this very specific case, because the temporary will be destroyed AFTER the whole line will execute, but in general is very bad to hold references to temporaries.

OTHER TIPS

Even if it's a temporary variable, that doesn't mean that all of its members are temporary. Inside the scope of your temp object, the this pointer and other members are not temporary. Your code is completely fine. Now if you did something like:

SomeFunc(&CCircleSetter(myCircle))

this would be a reference to a temp variable.

I don't think it's that a reference to a temporary is undefined, it's just forbidden. Also, I believe this only applies to function arguments. Visual Studio will allow you to pass references to non-const temporaries on the default warning/error level, though I know gcc will not.

As far as I know, doing so is only forbidden so programmers don't shoot themselves in the foot by storing a reference to a temporary that goes out of scope. Considering this is C++, I find that quite stupid.

I don't see any problem with what you're doing.

What you're doing is basically the same as in

if( istrm >> a >> b ) ...

which is the same as

if( istream.operator>>(a).operator>>(b).operator some_bool_like_type() )

I think this is fine from a usability POV. (There certainly are no syntactic/semantic problems with it.)

However, as always, implicit conversion to bool is a bit nasty, because it allows unexpected code to compile:

if ( CCircleSetter(myCircle).Radius(10) != 10 )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top