Boost logo

Boost :

From: scleary_at_[hidden]
Date: 2002-06-26 09:18:14

> -----Original Message-----
> From: Joe Swatosh [mailto:joe-swatosh_at_[hidden]]
> > -----Original Message-----
> > From: scleary_at_[hidden] [mailto:scleary_at_[hidden]]
> > I've messed around in the past with different versions of
> > classes that would
> > run arbitrary code when destroyed. Here's some different
> > functionality that
> > I've found useful:
> >
> > . Allow *any* action to be run; Boost.Functional can
> > already support this;
> > why have ScopeGuard duplicate this functionality?
> I'll confess my ignorance: I looked at Boost.Function and
> didn't see how it could help here.

You're right; it would only help if the declaration of a scope_guard object
had the template argument. The "const reference initializer" idiom pointed
out by Andrei avoids this, so I don't think ScopeGuard would benefit from
Function after all.

Using Function would allow a ScopeGuard that could be "rebound" (have its
action changed). But I think that goes against the idea of a ScopeGuard! :)

The "wrapper" functions, though, might benefit from Function. Or be
templated for a function object (which would make bind'ing more complex, but
that might be worked around without too much trouble).

> > . Have a type of ScopeGuard that wraps its action in
> > try...catch, similar
> > to the article, but have another type that does not.
> Yeah, I changed the version in the file section to not have
> the try/catch at all. It should be easy enough to write a
> wrapper function to catch everything if that is what is wanted.
> I also added tests that exit the block by throwing. In doing
> so I discovered that BCC isn't invoking the destructors
> during the stack unwind to the catch. Oh well.

I'll look at this some more and submit a bug report.

> > . Have a type of ScopeGuard that only runs its action if
> > the destructor
> > was called as part of stack unwinding, not normal block scope
> > exit (useful
> > for "rollback" operations).
> I assume you mean using uncaught_exception to figure that
> out. That's a neat idea. Obviously it won't work for VC6 users.

BCC has issues with it, too (it won't work for the RTL DLL, only the static
lib RTL). My BCB bugs page has a test case demonstrating this. :(

Upon reflection, this could also easily be done with another "wrapper":
  void only_during_unwinding(const function<void> & f)
    if (std::uncaught_exception())
      if (f)

> > . Have a type of ScopeGuard that follows strict scoping
> > rules, but have
> > another type whose scope can be "transferred" to a calling function.
> >
> > When you start looking at the different useful types of
> > ScopeGuard classes,
> > two things become apparent:
> > 1) It would be best as a policy-designed class
> I'd love to see scope_guard implemented in terms of
> boost::smart_resource or smart_pointer or whatever it turns
> out to be called. Right now, I see it as naming a point in
> the "'smart' resource management" space, in the same way that
> boost::scoped_ptr or std::auto_ptr do.

The concept of ScopeGuard would fall within Smart Resource Management, but I
think it could be deserving of its own special implementation; the const
reference initializer idiom is especially nice! :)

> > 2) It's very close to a SmartPtr. So close, in fact, that
> > I make the
> > claim that a ScopeGuard *is* a SmartPtr.
> Not sure I buy that one yet.

When I said it was a SmartPtr, I meant that its concepts fall within Smart
Resource Management -- and that therefore someday its functionality might be
covered by some massive SmartResource policy-based meta-class. Actually, I
think the name "SmartPtr"/"SmartResource" should be changed to "Master
Control Program" when it gets big enough... ;)


Boost list run by bdawes at, gregod at, cpdaniel at, john at