Creating a POD with a Variable Number of Elements

I would like to have a type that will actually be a POD, but I would like to be able to specify how and what types in it, for example:

template<Args...> struct POD { //here I would like to create depending on Args appropriate types as a members. }; 

Can this be done with this new function of variation templates in C ++ 0x?

+4
source share
2 answers

Ive never used the C ++ 0x variable template function, but the following code compiles in g ++ 4.5:

 template <typename... Args> struct tuple; template <typename T, typename... Args> struct tuple<T, Args...> { T value; tuple<Args...> inner; }; template <typename T> struct tuple<T> { T value; }; 

However, initializing them ... is strange, because we need to nest the internal values:

 int main() { tuple<int> n1 = { 23 }; tuple<int, float> n2 = { 42, { 0.5f } }; tuple<std::string, double, int> n3 = { "hello, world", { 3.14, { 97 } } }; } 

Retrieving values ​​is, of course, a little tedious. The simplest method is perhaps to create a template for the get<N>() function.

But we cannot implement get directly, since function templates cannot be partially specialized. Either we need to use SFINAE (read: boost::enable_if ), or we need to delegate the actual get function to a type that can be partially specialized.

Later I did the last. But first, we need another trait of the auxiliary type: nth_type , which returns the corresponding return type of the get function:

 template <unsigned N, typename... Args> struct nth_type; template <unsigned N, typename T, typename... Args> struct nth_type<N, T, Args...> : nth_type<N - 1, Args...> { }; template <typename T, typename... Args> struct nth_type<0, T, Args...> { typedef T type; }; 

Easy-Peasy. It simply returns the type n th in the type list.

Now we can write our get function:

 template <unsigned N, typename... Args> inline typename nth_type<N, Args...>::type get(tuple<Args...>& tup) { return get_t<N, Args...>::value(tup); } 

As I said, this simply delegates the task. No, biggie. In practice, we probably want to have a different overload for const tuples (but then in practice we would use the existing tuple type).

Now for the kill, followed by a light salad:

 template <unsigned N, typename... Args> struct get_t; template <unsigned N, typename T, typename... Args> struct get_t<N, T, Args...> { static typename nth_type<N, T, Args...>::type value(tuple<T, Args...>& tup) { return get_t<N - 1, Args...>::value(tup.inner); } }; template <typename T, typename... Args> struct get_t<0, T, Args...> { static T value(tuple<T, Args...>& tup) { return tup.value; } }; 

And here it is. We can verify this by printing some values ​​in our previously defined variables:

 std::cout << get<0>(n1) << std::endl; // 23 std::cout << get<0>(n2) << std::endl; // 42 std::cout << get<0>(n3) << std::endl; // hello, world std::cout << get<1>(n2) << std::endl; // 0.5 std::cout << get<1>(n3) << std::endl; // 3.14 std::cout << get<2>(n3) << std::endl; // 97 

Man, his funny messing around with variable patterns.

0
source

Are you familiar with std::tuple ?

AFAIK is POD, if all these are members of POD, if I am mistaken, then I assume that this is impossible.

0
source

All Articles