vendredi 19 juillet 2019

why my get

I copied a tuple implementation online, and it works find for most case:

template<class... Ts>
class tuple {};

template<class T, class... Ts>
class tuple<T, Ts...> : public tuple<Ts...> {
 public:
  tuple(T t, Ts... ts) : tuple<Ts...>(ts...), tail(t) {}
  T tail;
};

template<size_t, class>
struct elem_type_holder;

template<class T, class... Ts>
struct elem_type_holder<0, tuple<T, Ts...>> {
  typedef T type;
};

template<size_t k, class T, class... Ts>
struct elem_type_holder<k, tuple<T, Ts...>> {
  typedef typename elem_type_holder<k - 1, tuple<Ts...>>::type type;
};

template<size_t k, class... Ts>
typename std::enable_if<
    k == 0, typename elem_type_holder<0, tuple<Ts...>>::type &>::type
get(tuple<Ts...> &t) {
  return t.tail;
}

template<size_t k, class T, class... Ts>
typename std::enable_if<
    k != 0, typename elem_type_holder<k, tuple<T, Ts...>>::type &>::type
get(tuple<T, Ts...> &t) {
  tuple<Ts...> &base = t;
  return get<k - 1>(base);
}

For example, I wrote code like this:

tuple<int, int, int> mytuple(1, 2, 3);
std::cout << get<1>(mytuple) << std::endl;

"2" will print.

But I found if I create a subclass which inherit my custom tuple:

class Foo : public tuple<int, int, int> {
 public:
  Foo() : tuple<int, int, int>(1, 2, 3) {}
};

and create a object for Foo in main():

Foo foo;
td::cout << get<1>(foo) << std::endl;

the get() function will not work, the error is:

no matching function for call to ‘get<1>(Foo&)’

Then I test the std::tuple and std::get(), subclass of std::tuple works fine with std::get().

So what did I miss? How can I pass a subclass of my tuple like the stl?

Aucun commentaire:

Enregistrer un commentaire