Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C++0x -- mapping an argument pack to a set of indices.

0 views
Skip to first unread message

er

unread,
Nov 21, 2010, 11:17:42 AM11/21/10
to
Hello,

Here's what I'd like to achieve:

template<typename ...Args>
void g(Args&&...args){}

template<typename ...Args>
void f( std::tuple<Args...> const& t )
{
//g(
// std::get<0>( t ),
// ...,
// std::get<sizeof...(Args)>( t )
//);
}

Any suggestion, please?

Larry Evans

unread,
Nov 21, 2010, 12:37:07 PM11/21/10
to

what about:

g(std::get<Indices>(t)...)

where Indices is a parameter pack of indices.
Creating such an indices pack can be created with the
package_range_c template as shown here:


https://svn.boost.org/trac/boost/browser/sandbox/variadic_templates/libs/mpl/sandbox/tuple_non_recur.package_range_c.cpp#L54


Warning, NOT TESTED.

HTH.

-Larry

er

unread,
Nov 21, 2010, 8:04:51 PM11/21/10
to

>
> what about:
>
>   g(std::get<Indices>(t)...)
>
> where Indices is a parameter pack of indices.
> Creating such an indices pack can be created with the
> package_range_c template as shown here:
>
> https://svn.boost.org/trac/boost/browser/sandbox/variadic_templates/l...

>
> Warning, NOT TESTED.
>
> HTH.
>
> -Larry

Thanks. It seems to do more than I need but it definitely helped
thinking about the problem.

First, create a level of indirection between g() and f(),
f_impl(indices<I,Values...>, tuple). Second, Values... is mapped from
Args... using a straightforward recursion.

Below is a solution that compiled with GCC4.4 with flag -std=c++0x

#include <cstddef>
#include <tuple>
#include <iostream>

template<typename ...Args> struct pack_holder{};

template<typename I, I...Values> struct indices{};

namespace impl{

template<typename Indices,typename Pack> struct args_to_indices{};

template<typename I, I...Tail, typename T, typename... Rest>
struct args_to_indices<
indices<I, Tail...>,
pack_holder<T, Rest...>
>
{
typedef typename impl::args_to_indices<
indices<I, Tail..., sizeof...(Tail)>,
pack_holder<Rest...>
>::type type;
};

template<typename I, I...Tail>
struct args_to_indices<
indices<I, Tail...>,
pack_holder<>
>{
typedef indices<I, Tail...> type;
};

}// impl

template<typename I,typename...Args>
struct args_to_indices : impl::args_to_indices<
indices<I>,
pack_holder<Args...>
>{};

void g(){}

template<typename T,typename...Args>
void g(T&& t, Args&&...args)
{
std::cout << t << ' ';
g( args... );
}


template<typename I,I ...Values, typename T>
void f_impl(indices<I, Values...>, T const& t )
{
g( std::get<Values>( t )...);
}


template<typename ...Args>
void f( std::tuple<Args...> const& t )
{

typedef int int_;
typedef typename args_to_indices<int_,Args...>::type indices_;
f_impl(indices_(), t);
}

int main(){

typedef std::tuple<int, const char*, double> tuple_;
tuple_ t(12, "Hello", 43.56);
f( t ); // outputs 12 "Hello" 43.56

return 0;
}

er

unread,
Nov 21, 2010, 8:21:12 PM11/21/10
to
PS:

> First, create a level of indirection between g() and f(),

Improper phrasing, in hindsight. A layer between.

>
> template<typename T,typename...Args>
> void g(T&& t, Args&&...args)
> {
>     std::cout << t << ' ';
>     g( args... );
>
> }


Maybe g( std::forward<Args>( args )... ) is safer...

0 new messages