#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));
}
上面用g++ test_templated_lambda.cpp -o test_templated_lambda -std=c++14
编译,但不用clang++ test_templated_lambda.cpp -o test_templated_lambda -std=c++14
编译
我知道这是一个GCC扩展(Using template parameter in a generic lambda),但有一些方法可以做到这一点,而无需将g
作为自由函数写出来
答案 0 :(得分:3)
如果没有一些外部帮助,这是不可能的;泛型lambda是函数范围内允许的唯一模板形式,它们不能专门化或重载(没有一些外部帮助,例如P0051R1 overload
)。
可以通过在函数中嵌入递归泛型lambda来编写编译时循环,但是(a)你必须将它转换为定点组合形式, (b)终止它是非常丑陋的:
[&](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);
});
您已经在使用外部帮助工具(std::index_sequence_for
),为什么不写另一个呢?例如:
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>{}...);
}
用法:
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...>());