Implementation of static_for to iterate over elements of std::tuple using C++17 features
IMHO, I think this is indeed pretty ugly. Assuming you just want to iterate over all of the elements of tuple (which is what you've done here), you can simplify this both in implementation and in usage:

template &lt;class Tup, class Func, std::size_t ...Is&gt;
constexpr void static_for_impl(Tup&amp;&amp; t, Func &amp;&amp;f, std::index_sequence&lt;Is...&gt; )
{
    ( f(std::integral_constant&lt;std::size_t, Is&gt;{}, std::get&lt;Is&gt;(t)),... );
}

template &lt;class ... T, class Func &gt;
constexpr void static_for(std::tuple&lt;T...&gt;&amp;t, Func &amp;&amp;f)
{
    static_for_impl(t, std::forward&lt;Func&gt;(f), std::make_index_sequence&lt;sizeof...(T)&gt;{});
}

int main()
{
    auto t = std::make_tuple( 1, 22, 3, 4 );

    std::size_t weighted = 0;
    static_for(t, [&amp;] (auto i, auto w) { weighted += (i+1) * w; });

    std::cout &lt;&lt; "Weighted: " &lt;&lt; weighted &lt;&lt; std::endl;

    return 0;
}


This is more like for_each, or maybe for_each + enumerate from python. On the implementation side, you no longer need this wrapper stuff. On the usage side, the lambda just directly gets passed the index and the the element, so it doesn't need to extract it from the tuple. Note that I pass the integer by "type" so that you can do crazy things with it but for most purposes it would probably just be simpler to pass an actual size_t as the first argument. Though integral_constant does implicitly convert anyhow.

If you wanted to iterate over multiple tuples or something like that (very rare), you could take my approach and modify it so that the lambda only gets passed the first argument, and then captures the tuple and uses std::get&lt;i&gt; to index into it. But you still don't need the wrapper struct or w.n.