0

I'm playing around with variadic function templates in C++11 and have got the basic idea with code something like:

void helper() { std::cout << "No args" << std::endl; } template< typename T > void helper( T&& arg ) { size_t n = 0; std::cout << "arg " << n << " = " << arg << std::endl; helper(); } template< typename T, typename... Arguments > void helper( T&& arg, Arguments&& ... args ) { size_t n = sizeof...( args ); std::cout << "arg " << n << " = " << arg << std::endl; helper( args... ); } 

However, what I want is for the argument number (the variable n in the code) to count up rather than down. How can I do this elegantly? I could write a wrapper function that creates a 'hidden' argument count but I feel there should be a neater way?

Thanks!

2 Answers 2

2

Do you mean something like this? I think I understand what you're looking for, but if not I'll not hesitate to drop this answer:

#include <iostream> #include <utility> void helper() { std::cout << "no args" << std::endl; } template<size_t N, typename T> void helper(T&& arg) { std::cout << "arg " << N << " = " << arg << std::endl; } template<size_t N, typename T, typename... Args> void helper(T&& arg, Args&&... args) { helper<N>(std::forward<T>(arg)); helper<N+1, Args...>(std::forward<Args>(args)...); } template<typename T, typename... Args> void helper(T&& arg, Args&& ... args) { helper<0>(std::forward<T>(arg), std::forward<Args>(args)... ); } int main() { helper(); std::cout << '\n'; helper("single"); std::cout << '\n'; helper("one", 2U); std::cout << '\n'; helper(1,"two", 3.0, 4L); std::cout << '\n'; return 0; } 

Output

no args arg 0 = single arg 0 = one arg 1 = 2 arg 0 = 1 arg 1 = two arg 2 = 3 arg 3 = 4 

See it live

Sign up to request clarification or add additional context in comments.

2 Comments

This is almost identical to the solution I've currently been using with a 'hidden' N so not quite what I'm getting at. Don't drop the answer though because it's imo the neatest so far :)
@user2746401 Sure. The thing I was trying to get to was calculating the parameter index via a template-argument that carries it along. It doesn't introduce any run-time variable, which I understood (perhaps incorrectly) was your goal in doing this while addressing ascend-vs-descend index direction. In the end the template arguments at compile-time manage the index; not a passed-along var. Its all a compile-time expansion (as yours is) but in the right direction. Glad it was worth some brain-food.
0

You may do the following: live example

#if 1 // Not in C++11 // make_index_sequence #include <cstdint> template <std::size_t...> struct index_sequence {}; template <std::size_t N, std::size_t... Is> struct make_index_sequence : make_index_sequence<N - 1, N - 1, Is...> {}; template <std::size_t... Is> struct make_index_sequence<0u, Is...> : index_sequence<Is...> {}; #endif // make_index_sequence namespace detail { template<std::size_t...Is, typename... Ts> void helper(index_sequence<Is...>, Ts&&...args) { int dummy[] = {0, ((std::cout << "arg " << Is << " = " << args << std::endl), 0)...}; static_cast<void>(dummy); } } void helper() { std::cout << "No args" << std::endl; } template<typename ... Ts> void helper(Ts&&... args) { detail::helper(make_index_sequence<sizeof...(Ts)>(), std::forward<Ts>(args)...); } 

3 Comments

Thanks but, as mentioned in my question, I was hoping to avoid writing such a wrapper that then creates a hidden argument with the argument numbers.
@user2746401: Why? It's a pretty clean way.
@Xeo: imo I don't think the answer is particularly clean and I think my current solution (similar to WhozCraig's) is cleaner and more readable.Perhaps I didn't phrase my question as best I could. I'm trying to find out if there is an inbuilt way - integral to variadic templates - that carries the original argument number along in the parameter pack.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.