1

I have written a template-based factory system for a project I'm working on. These are the signatures for some of the function templates I have:

template <typename Interface, typename... Args>
void register_factory(identifier id, function<shared_ptr<Interface> (Args...)> factory);

template <typename Interface, typename... Args>
void unregister_factory(identifier id);

template <typename Interface, typename... Args>
shared_ptr<Interface> create(identifier id, Args... args);

As you see, I have to give all my function templates a typename... Args argument, because I need to access the variables in which I store factory functions:

template <typename Interface, typename... Args>
struct factory_storage {
  static map<identifier, function<shared_ptr<Interface> (Args...)> factories;
};

But logically, I should only need those for register_factory and create, everywhere else knowing Interface should suffice (all factory functions for the same interface have the same signature). In fact, if I had used void* instead of std::function, I could have gotten rid of most occurrences of typename... Args in my code.

Is there a way I could keep the type-safety of std::function and also avoid some of the clutter. I've seen std::tuple used for storing typename... arguments, and those could be one possible solution to my problem, but they seem overly complicated and I'm hoping to be able to avoid them.

Elektito
  • 3,863
  • 8
  • 42
  • 72
  • [This may be related](http://stackoverflow.com/questions/18251815/creating-an-array-initializer-from-a-tuple-or-variadic-template-parameters), I used it to solve a similar problem. – πάντα ῥεῖ May 25 '14 at 06:55
  • As the user have to remember the matching between `id` and `Args` type, does it make sense to return a template class ID based on `Interface` and `Args` instead of simple `identifier id` ? – Jarod42 May 25 '14 at 10:37
  • I need to make an `std::function(Args...)` function type in any case. How could I construct that type if I don't receive Interface and Args as template arguments? – Elektito May 25 '14 at 10:49
  • @Elektito: I mean if `id` was something like `identifier`, the template arguments you want can be deduced from `id`. – Jarod42 May 26 '14 at 07:10
  • That might be possible, but `identifier` here is an int typedef, widely used throughout the code for various purposes. I'd need to change a lot of code to make it like this. – Elektito May 26 '14 at 07:21

1 Answers1

1

If the number of signature of std::function are fixed, a variant (as the one from Boost) is a possible solution.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • That is not the case, I'm afraid. This is a library, and I have no control over how it is going to be used later. – Elektito May 25 '14 at 10:21