On Thu, Aug 18, 2011 at 1:04 PM, Nat Linden <nat@lindenlab.com> wrote:
On Wed, Aug 17, 2011 at 10:49 AM, Brian Allison
<brian.w.allison@gmail.com> 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@lists.boost.org
http://lists.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";
   }