daedalic
daedalic

Reputation: 103

How do I get elements from a variadic tuple?

So, I made a simple tuple class using variadic templates...

How would I go about making a working get method/helper function? The current one I'm using causes the compiler to expect a get defined in the empty tuple.

Here's the code:

template<typename... T>
class tuple;

template< > 
class tuple< > { };

template<typename U, typename... T>
class tuple<U, T...>
{
public:
  tuple () {};
  tuple (U f, T... r);

  U get (int idx, int numCalls = 0) const;

  U first_;
  tuple<T...> rest_;
};

template<typename U, typename... T>
tuple<U, T...>::tuple (U f, T... r)
{
  first_ = f;
  rest_ = tuple<T...> (r...);
}

template<typename U, typename... T>
U tuple<U, T...>::get (int idx, int numCalls) const
{
  if (idx == numCalls)
    return first_;

  return rest_.get (idx, numCalls + 1);
}

Thanks for any help!

Upvotes: 0

Views: 522

Answers (2)

Kerrek SB
Kerrek SB

Reputation: 477070

Add a specialization for one type as well as for zero types:

template <typename T>
class tuple
{
  T first_;

  // get() ...
}

Note that your design is hugely inefficient. First off, the get index should really be a compile-time constant parameter, so you want get<i> (like std::tuple does). Your run-time code contains no error checking, and invalid invocation cannot be caught at compile time. Second, all your constructors perform a large number of copies that should probably be modified to allow for perfect forwarding.

Upvotes: 1

Daniel
Daniel

Reputation: 31579

To get your current code working, make a get function in empty tuple returning nothing.
Alternatively, a better solution it to make get with a parameter of the number of argument you like:

template<typename U, int N>
U get()

and then make it pass forward with reduced N, and when N is 0, specialize it to return the element.

Upvotes: 0

Related Questions