2016-02-12 3 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++14Generic лямбда-функции с параметрами шаблона

Я знаю, что это расширение GCC (Using template parameter in a generic lambda), но есть какой-то способ сделать это без написания out g как бесплатная функция

ответ

2

Это невозможно без какой-либо внешней помощи; generic lambdas - единственная форма шаблона, разрешенная в пределах области действия, и они не могут быть специализированными или перегруженными (без какого-либо внешнего помощника, такого как P0051R1overload).

Это является можно написать цикл времени компиляции путем встраивания рекурсивного общий лямбда в вашей функции, но (а) вам придется преобразовать его в неподвижной точке формы комбинатора, и (б) прекращения его серьезно уродливый:

[&](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

Смежные вопросы