$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [Boost-users] Scoped Pairs of functions?
From: Brian Allison (brian.w.allison_at_[hidden])
Date: 2011-08-19 07:00:09
On Thu, Aug 18, 2011 at 1:04 PM, Nat Linden <nat_at_[hidden]> wrote:
> On Wed, Aug 17, 2011 at 10:49 AM, Brian Allison
> <brian.w.allison_at_[hidden]> wrote:
>
> >   I'm on a project which uses a C++ compiler, but with a lot of C-isms.
> One of those is that there are objects with pairs of functions which
> allocate/deallocate resources. I don't have time to fix all of the design
> issues with the classes that do this (yet), but within one compilation unit
> I'd like to remove the chance for leaks.
> >
> >   So - if I wanted to use boost types to wrap around 2 functions f() and
> g(), where each function
> >
> > has a void or primitive return type
> > takes zero or 1 argument
> > where f() is called at some point in a scope, and then g() is called on
> exiting the scope from which f() is called and only if f() doesn't throw..
> > has its return value ignored. [Gahh....]
> >
> > Is there a boost::bind (or lambda) expression that I can wrap in a type?
> >
> > How do I generalize to include the possibility of a single argument?
>
> The following works for me with gcc 4.0.1 (yeah, I know, old compiler):
>
> #include <iostream>
> #include <boost/function.hpp>
> #include <boost/bind.hpp>
>
> void acquire_fixed()
> {
>    std::cout << "Acquiring fixed resource\n";
> }
>
> void release_fixed()
> {
>    std::cout << "Releasing fixed resource\n";
> }
>
> void acquire(const std::string& resource)
> {
>    std::cout << "Acquiring " << resource << '\n';
> }
>
> void release(const std::string& resource)
> {
>    std::cout << "Releasing " << resource << '\n';
> }
>
> class ScopedResource
> {
> public:
>    typedef boost::function<void()> ResourceFunc;
>    ScopedResource(const ResourceFunc& acq, const ResourceFunc& rel):
>        mRelease(rel)
>    {
>        acq();
>    }
>
>    virtual ~ScopedResource()
>    {
>        mRelease();
>    }
>
> private:
>    ResourceFunc mRelease;
> };
>
> int main(int argc, char *argv[])
> {
>    {
>        ScopedResource fixed(acquire_fixed, release_fixed);
>        std::cout << "during lifespan of 'fixed'\n";
>    }
>    {
>        ScopedResource something(boost::bind(acquire, "something"),
>                                 boost::bind(release, "something"));
>        std::cout << "during lifespan of 'something'\n";
>    }
>    return 0;
> }
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://listarchives.boost.org/mailman/listinfo.cgi/boost-users
>
Is there a way to generalize the return type so that ScopedResource could be
in a library and the user could use it for pairing two functions that have
int and void return types respectively?
I'm not familiar with boost::function, so I don't know if I could mod the
class and typedef to:
template *<type R1 = void, type R2 = void>*
class ScopedResource
{
public:*
   typedef boost::function<R1()> ResourceFunc1;  *  // will this work?*
   typedef boost::function<R2()> ResourceFunc2; *   // will this work?*
*
and the object declarations as
   {
       ScopedResource fixed(acquire_fixed, release_fixed);
       std::cout << "during lifespan of 'fixed'\n";
   }
   {
       ScopedResource*<void, int>* something(*f_that_returns_int,
g_with_void_return*);
       std::cout << "during lifespan of 'something'\n";
   }