Alexander Frolov Alexander Frolov - 3 months ago 20
C++ Question

How to create custom integer sequence in C++

I have some function like this:

template <typename ... Types>
void foo(const Types & ... values)
{
// expected that 'values' is sequence like
// '1, customvalue1, 2, customvalue2, 3,...'
}


And second function:

template <typename ... Types>
void bar(const Types & ... values)
{
// where 'values' are any variables
// some magic here
foo((int_seq<sizeof...(Types)>, values)...);
}


I'd like to pass any sequence of variables to bar, so that this sequence convert to sequence like '1, value1, 2, value2, 3, value3'. So each value follows its number in base sequence. But I cannot create this 'magic code' to transform sequence on compile phase between this two state.

Answer

Not really elegant but, using tuples, std::tie, etc...

The following example should work with C++11

--- EDIT ---

Modified and unified (C++11 without C++14 elements) my first example.

There is no need of std::index_sequence (a trivial struct indSeq can be used instead) or std::make_index_sequence (the index sequence can be contructed step by step using sizeof...(I)); no need of qux() anymore.

#include <tuple>
#include <iostream>


void foo ()
 { }

template <typename T0, typename ... Types>
void foo (const T0 & v0, const Types & ... values)
 {
   std::cout << "-- " << v0 << std::endl;

   foo(values...);
 }


template <std::size_t ...>
struct indSeq
 { };

template <std::size_t ... Is, typename ... Ts1>
void baz (std::size_t, const indSeq<Is...> &, const std::tuple<Ts1...> & t)
 { foo(std::get<Is>(t)...); }

template <std::size_t ... Is, typename ... Ts1, typename T0, typename ... Ts2>
void baz (std::size_t n, const indSeq<Is...> &, const std::tuple<Ts1...> & t,
          const T0 & v0, const Ts2 & ... vs)
 { baz(n+1U, indSeq<Is..., sizeof...(Is), sizeof...(Is)+1U>(),
       std::tuple_cat(t, std::tie(n), std::tie(v0)), vs...); }

template <typename ... Types>
void bar (const Types & ... values)
 { baz (1U, indSeq<>(), std::tuple<>(), values...); }

int main()
 {
   bar(11, 22L, "33", 44.44);
   return 0;
 }

p.s.: sorry for my bad English.

Comments