Search code examples
c++templatesc++14variadic-templates

How do I transform all elements of a varadic std::tuple using numerical indices?


Currently, I have an implementation like this in order to transform all values of a tuple using a function bar() that takes in each element of the tuple.

template<typename ... Args>
void foo(const std::tuple<Args...>& a)
{
    std::tuple<Args...> transformedTuple = std::make_tuple(bar(std::get<Args>(a))...);
}

The problem with this is that this will no longer work if Args contains duplicate types. Hence, I would like to change the std::get<> call to use numerical indices into the tuple instead of using types. Given that my development environment is stuck on C++14, is there any way of getting this to work? Thanks!


Solution

  • You can use a helper function that takes a std::integer_sequence to do this. Add a helper function that takes an integer_sequence like

    template<typename Tuple, std::size_t... I>
    auto foo_helper(const Tuple& a, std::integer_sequence<std::size_t, I...>)
    {
        return std::make_tuple(bar(std::get<I>(a))...);
    }
    
    

    And then changing foo to call the helper like

    template<typename ... Args>
    auto foo(const std::tuple<Args...>& a)
    {
        return foo_helper(a, std::make_index_sequence<sizeof...(Args)>{});
    }
    

    Live demo