2016-02-12 74 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