2016-02-12 71 views
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)); 
} 

以上编译与g++ test_templated_lambda.cpp -o test_templated_lambda -std=c++14,但不与clang++ test_templated_lambda.cpp -o test_templated_lambda -std=c++14通用lambda函数

编译我知道这是一个GCC扩展(Using template parameter in a generic lambda),但有一些方法来做到这一点没有写出g作为一个自由函数

回答

2

这是不可能没有一些外部的帮助;通用lambda表达式是一个功能范围内允许模板的唯一形式,它们不能被专门或重载(没有一些外部辅助,诸如P0051R1overload)。

可能通过在函数中嵌入递归通用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); 
}); 

Example

您已经在使用一个外部辅助设施(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...>()); 
+0

有用的。但我试图避免定义另一个效用函数 – zrb