4
 #include <utility>
 #include <tuple>

 template < typename T, typename U >
 void h(T, U)
 {
 }

 template < typename... T, typename... U >
 void f(std::tuple < T... >  t, std::tuple < U... >  u)
 {
     auto g = [&] < std::size_t... I > (std::index_sequence < I... >)
              {
                  bool const r[]{((void)h(std::get < I >(t), std::get < I >(u)), false)...};
                  (void)r;
             };
     g(std::index_sequence_for < T... >());
 }

 int main()
 {
     f(std::make_tuple(0L, 0LL), std::make_tuple(0UL, 0ULL));
 }

The above compiles with g++ test_templated_lambda.cpp -o test_templated_lambda -std=c++14, but doesn't compile with clang++ test_templated_lambda.cpp -o test_templated_lambda -std=c++14

I know it is a GCC extension (Using template parameter in a generic lambda), but is there some way to do this without writing out g as a free function

0

1 Answer 1

3

This is not possible without some external help; generic lambdas are the only form of template permitted within a function scope, and they cannot be specialized or overloaded (without some external helper, such as P0051R1 overload).

It is possible to write a compile-time loop by embedding a recursive generic lambda in your function, but (a) you'll have to convert it to fix-point combinator form, and (b) terminating it is seriously ugly:

[&](auto&& g) {
  g(g, std::integral_constant<std::size_t, 0u>{});
}([&](auto&& g, auto I) {
  h(std::get<I>(t), std::get<I>(u));
  std::get<I + 1 == sizeof...(T)>(std::make_pair(
    [&](auto&& g) { g(g, std::integral_constant<std::size_t, I + 1>{}); },
    [](auto&&){}))(g);
});

Example.

You're already using an external helper facility (std::index_sequence_for), so why not write another? For example:

template<class F, std::size_t... I> auto apply_indexes(F&& f, std::index_sequence<I...>) {
  return std::forward<F>(f)(std::integral_constant<std::size_t, I>{}...);
}

Usage:

auto g = [&](auto... I)
{
  bool const r[]{((void)h(std::get<I>(t), std::get<I>(u)), false)...};
  (void)r;
};
apply_indexes(g, std::index_sequence_for<T...>());
Sign up to request clarification or add additional context in comments.

1 Comment

Helpful. But I am trying to avoid defining another utility function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.