I would like to write an object generator for a templated RAII class -- basically a function template to construct an object using type deduction of parameters so the types don't have to be specified explicitly.
The problem I foresee is that the helper function that takes care of type deduction for me is going to return the object by value, which will (**) result in a premature call to the RAII destructor when the copy is made. Perhaps C++0x move semantics could help but that's not an option for me.
Anyone seen this problem before and have a good solution?
This is what I have:
template<typename T, typename U, typename V>
class FooAdder
{
private:
  typedef OtherThing<T, U, V> Thing;
  Thing &thing_;
  int a_;
  // many other members
public:
  FooAdder(Thing &thing, int a);
  ~FooAdder();
  FooAdder &foo(T t, U u);
  FooAdder &bar(V v);
};
The gist is that OtherThing has a horrible interface, and FooAdder is supposed to make it easier to use.  The intended use is roughly like this:
FooAdder(myThing, 2)
  .foo(3, 4)
  .foo(5, 6)
  .bar(7)
  .foo(8, 9);
The FooAdder constructor initializes some internal data structures.  The foo and bar methods populate those data structures.  The ~FooAdder dtor wraps things up and calls a method on thing_, taking care of all the nastiness.
That would work fine if FooAdder wasn't a template.  But since it is, I would need to put the types in, more like this:
FooAdder<Abc, Def, Ghi>(myThing, 2) ...
That's annoying, because the types can be inferred based on myThing.  So I would prefer to create a templated object generator, similar to std::make_pair, that will do the type deduction for me.  Something like this:
template<typename T, typename U, typename V>
FooAdder<T, U, V>
AddFoo(OtherThing<T, U, V> &thing, int a)
{
  return FooAdder<T, U, V>(thing, a);
}
That seems problematic: because it returns by value, the stack temporary object will (**) be destructed, which will cause the RAII dtor to run prematurely.
** - if RVO is not implemented.  Most compilers do, but it is not required, and can be turned off in gcc using -fno-elide-constructors.
 
     
     
     
     
     
     
    