0

My apologies if this has been asked before - searched with no definite answer, and I'm beginning to wonder if it is even possible. I am trying to learn C++11 and have run into trouble with variadic templates. I think I grasp (finally) the concept of variadic function parameters, and why/how recursion is used to unwrap and process them, but am having trouble with a (I think) similar concept in class constructors.

Suppose I want to create a variadic template class that has a mixed-type container (assume tuple) as a private member. Is it possible to push an arbitrary number of variously-typed objects into that tuple when the class object is constructed? Something like:

#include <tuple>

// forward declaration - is this needed?
template <class ... args>
class myClass;

template <class H, class ... T>
class myClass <H, T ...>
{
 private:
     std::tuple<anything can go here> mycontainer;
 public:
     myClass(const H& head, const T& ... tail)
     {
            push head into mycontainer;
            do some sort of recursion with tail;
     }
}

I've been screwing around with std::tuple_cat and std::make_tuple and thought that I was on to something for a while, but no luck.

It has been a long time since I've had anything to do with C++, so my apologies if I'm totally off my nut. I just started looking at this after doing some reading about the C++11 features.

EDIT: Just adding that I'm on GCC 4.8.x and/or Visual Studio 2012

thekamz
  • 13
  • 5
  • Note that the release version of VS2012 doesn't support variadic templates: you'll need to get the November 2012 CTP compiler release or the VS2013 preview if you want variadics in VS. – Casey Jul 19 '13 at 02:49
  • @Casey : Thank you. I'll get the 2013 preview. – thekamz Jul 19 '13 at 09:12

1 Answers1

1

Yes, it's possible to construct a member from some of those variadic types. For example:

template <class ... T>
class myClass {
  std::tuple<T...> mytuple;
public:
  // Constructor that takes const refs to the Ts and constructs tuple:
  myclass(const T&... args) : mytuple(args...) {}

  // Perfect forwarding constructor that will try to construct tuple
  // from arbitrary lvalue/rvalue parameters:
  template <class... Args>
  myclass(Args&&... args) : mytuple(std::forward<Args>(args)...) {}
};

If you're asking for something more specific, you'll have to describe it in more detail.

Casey
  • 41,449
  • 7
  • 95
  • 125
  • Thank you; I'll need to read up on the perfect forwarding constructor. I guess I'm nowhere near as prepared as I thought. Using this, it seems like it is possible to implement a myclass.get(int) that will use the get(int) function of std::tuple like this: `auto get(int element) -> decltype(mytuple.get(element)) { return mytuple.get(element); } ` But this seems clumsy. What would the right way be? – thekamz Jul 19 '13 at 09:05
  • Whoops, I meant std::get<1>(mytuple) – thekamz Jul 19 '13 at 09:18
  • OK my bad, I am totally lost. Reading time! @Casey : Thanks for the head start. – thekamz Jul 19 '13 at 09:40
  • Is there any reason you chose `forward` over `move`? – Francis Cugler Jun 21 '19 at 00:06