Я предлагаю вам взглянуть на VARIADIC шаблона. typename... Ts
не является массивом. Поэтому вы не можете ожидать, что Args... v
будет расширен как массив. Кроме того, как вы создадите массив с каждым элементом разного типа?
Ваше требование довольно похоже на то, что дает std::tuple
, вы должны взглянуть на его реализацию.
Посмотрите на this GoingNative 2012 video от Andrei. Это отличное введение в вариационный шаблон.
И вот одна из моих игрушек tuple
, когда игра с VARIADIC шаблона. Есть кое-что дублирование с тем, что C++ 11 stl, но его игрушка в любом случае.
#include <iostream>
#include <vector>
#include <typeinfo>
#include <type_traits>
using namespace std;
template <typename T, typename... Ts> class MyTuple : public MyTuple<Ts...> {
using base = MyTuple<Ts...>;
public:
T elem;
MyTuple(T v, Ts... vs) : base(vs...), elem(v) {}
};
template <typename T> class MyTuple<T> {
public:
T elem;
MyTuple(T v) : elem(v) {}
};
template <int i, typename T, typename... Ts> struct type_of {
static_assert(i < sizeof...(Ts) + 1, "index out of range");
typedef typename type_of<i - 1, Ts...>::type type;
};
template <typename T, typename... Ts> struct type_of<0, T, Ts...> {
typedef T type;
};
template <int i, typename T, typename... Ts>
typename enable_if<i == 0, typename type_of<i, T, Ts...>::type&>::type get(MyTuple<T, Ts...> &t) {
static_assert(i >= 0, "index out of range");
static_assert(i < sizeof...(Ts) + 1, "index out of range");
return t.elem;
}
template <int i, typename T, typename... Ts>
typename enable_if<i != 0, typename type_of<i, T, Ts...>::type&>::type get(MyTuple<T, Ts...> &t) {
static_assert(i >= 0, "index out of range");
static_assert(i < sizeof...(Ts) + 1, "index out of range");
MyTuple<Ts...>& base = t;
return get<i - 1>(base);
}
int main(int argc, char const *argv[]) {
cout << typeid(type_of<0, int, char, long>::type).name() << endl; // print i
cout << typeid(type_of<1, int, char, long>::type).name() << endl; // print c
cout << typeid(type_of<2, int, char, long>::type).name() << endl; // print l
MyTuple<int, int> t(0, 1);
cout << get<0>(t) << endl;
cout << get<1>(t) << endl;
return 0;
}
Прост в использовании 'std :: tuple'. – chris
Вам нужно взглянуть на вариационный шаблон. Вы используете его неправильно. –
@chris - Спасибо, но моя задача - избежать «std :: tuple» – Joe