2014-01-06 3 views
1

В C++, как я могу получить доступ к элементам вариационного шаблона, например массива? Я сделал основную попытку показать, что я пытаюсь для того чтобы достигнуть ниже, но, конечно, он не компилируется:C++ Variadic Template Array/Accessing Elements

template<class... Args> struct Apple{ 
public: 
    Apple(Args... A) : V(A){} 
    Apple() : p(0){} 
    void push_back(decltype(V[p]) v){ 
     V[p++] = v; 
    } 
private: 
    Args... V; 
    int p; 
}; 

int main(){ 
    Apple<int, double> a(5, 6.5); 
    Apple<int, double> b; 
    b.push_back(5); 
    b.push_back(6.5); 
} 
+2

Прост в использовании 'std :: tuple'. – chris

+0

Вам нужно взглянуть на вариационный шаблон. Вы используете его неправильно. –

+0

@chris - Спасибо, но моя задача - избежать «std :: tuple» – Joe

ответ

2

Я предлагаю вам взглянуть на 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; 
} 
Смежные вопросы