1

I am unsure of what the proper name is, so far I comprehend the notion of using variadic template arguments (e.g., in comparison to std::initializer_list).

So let's assume there is an arbitrary number of classes k and an arbitrary number of parameters i which is dependant on each class k constructor.

I know that I may construct any class k using a variadic template:

template <typename T, typename... Args>
void make_class(Args... args)
{
    auto k = T(args...);
}

However I want to allow creation of multiple classes which are not of the same type and most likely have different Args. Furthermore, I want to iterate the classes k being constructed. Something along the lines:

template <typename T, typename... Classes, typename Args>
void make_classes(Classes... classes)
{
    for (auto type : classes) {
        make_class<T>(args...); //???
    }   
}
  1. Is this possible?
  2. If not possible, are there any potential work-arounds?
  3. Is there a name for such a pattern/approach? Is this a parameter_pack?

Apologies if this is a duplicate.

Ælex
  • 14,432
  • 20
  • 88
  • 129
  • The current title is very unclear. Are you asking whether it's possible to pass around a parameter pack that consists of an arbitrary number of arbitrary parameter packs? If so, then it's not possible in so many words - since how would the compiler determine where each 'sub-pack' ends and the next begins - _but_ you might be able to achieve the same effect by passing around a parameter pack wherein each element is a templated `tuple`, then use an existing implementation of [`make_from_tuple`](http://en.cppreference.com/w/cpp/utility/make_from_tuple) to unpack each – underscore_d Aug 26 '16 at 14:13
  • ...but I'll leave the extreme `template` experts to clarify whether/how that would be done exactly, as it's a bit over my head. I've only ever done it with known numbers of `tuple`s, not a variadic set thereof. – underscore_d Aug 26 '16 at 14:18
  • @underscore_d sorry if it wasn't clear, as I understood it I thought it was an issue of nesting. Probably it isn't. Yet this is what I am asking: how can the template function take an arbitrary number of classes, and for each class, its own arbitrary number of parameters. I assume that determination would be done at compile time by the actual method call, since they would have to be defined, but thinking of it now maybe your sugggestion is simpler. – Ælex Aug 26 '16 at 14:22
  • @underscore_d I'm also guessing there's the issue of finding out how each parameter corresponds to each class constructor, therefore I'm guessing its not possible to do it this way. – Ælex Aug 26 '16 at 14:26
  • Well, both the list of class types and the pack of `tuple`s would be ordered, but yeah, they'd probably need to be separated too... and in terms of invoking them in a loop, I'm not sure - might still require ye olde style recursive `template`s, unless there's a more modern construct for it. – underscore_d Aug 26 '16 at 14:27
  • @underscore_d could you please provide an example? Maybe I could forward the arguments via a struct containing the type and its arguments... – Ælex Aug 26 '16 at 14:30
  • 1
    Believe me: I wish I could! I'm just not quite at that level of `template` wizardry yet. I hope someone who is can chime in. – underscore_d Aug 26 '16 at 14:32

1 Answers1

2

You'll need to delineate the arguments for each class by passing them in a tuple, since otherwise the result could be ambiguous for classes with more than one constructor (and note that most classes have at least a default constructor and copy constructor).

That done, this is easy to write:

template<class... Classes, class... Args>
void make_classes(Args&&... args) {
    auto k = std::tuple<Classes...>{
        std::make_from_tuple<Classes>(std::forward<Args>(args))...};
}

Usage:

make_classes<std::pair<int, float>, std::string, std::vector<double>>(
    std::forward_as_tuple(42, 3.14f),
    std::forward_as_tuple("hello"),
    std::forward_as_tuple(5, 99.99));

Example.

Note that make_from_tuple is a C++17 library addition; if your library doesn't have it you can copy the example implementation.

ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • Thank you very much, this is a lot simpler than what I was planning. Unfortunately I use C++11 but I'll just copy it as you suggested. I guess iteration is a matter of accessing the tuple items? – Ælex Aug 26 '16 at 14:49
  • 1
    @Ælex C++11, huh. You'll also probably need an implementation of `make_index_sequence`; see e.g. http://stackoverflow.com/a/20817081/567292 – ecatmur Aug 26 '16 at 14:54
  • @Ælex iteration - yes, there's plenty of questions here about how to iterate over members of a tuple. – ecatmur Aug 26 '16 at 14:57
  • I ended up using a slight variation of what you proposed, which is more limited but appears to be a bit more easy for me to comprehend: https://ideone.com/Fq242E but I wouldn't have done it without your reply. – Ælex Aug 26 '16 at 17:08