0

Использование прозрение this question (и несколько других) я смог написать следующее для опрашивая нормальной функции лямбда типа инфокоммуникационных (т.е. тип возвращаемого значения, считать аргумент и т.д.)Специализируется шаблонов на C++ AMP ограниченной лямбдах

// helper classes ======================================== 
template <typename R, typename... A> 
class lambda_traits_evaluation { 
public: 
    typedef R r_type; 
    enum { n_args = sizeof...(A) }; 
    // ... 
}; 

template <typename R, typename... A> 
class lambda_traits_helper 
    : public lambda_traits_evaluation<R,A...>{}; 

template <typename R, typename F, typename... A> 
class lambda_traits_helper<R (F::*)(A...) const> 
    : public lambda_traits_evaluation<R,A...>{}; 

// use class  ======================================== 
template <typename F> 
class lambda_traits { 
    typedef typename lambda_traits_helper<decltype(&F::operator())> helper_impl; 
    // ... 
} 

затем я могу использовать это с lambda_traits<decltype(myLambda)> но где моим самодовольным кодирование заканчивается, потому что, если моя лямбда усилитель ограничен для графического процессора т.е.

auto myLambda = [](int) restrict(amp) -> void {}; 

, как очевидно, специализация шаблона не забирается. Однако при добавлении новой специализации

template <typename R, typename F, typename... A> 
class lambda_traits_helper<R (F::*)(A...) const restrict(amp)> 
    : public lambda_traits_evaluation<R,A...> {}; 

еще не решает проблему, как я обнаружил, что компилятор лает

error C3939: 'abstract declarator' : pointer to member functions, function 
      pointers, references to functions with 'amp' restriction 
      specifier are not allowed 

есть другой способ, чтобы опрашивать типы в лямбды или же способ обирать ограничить от лямбда-типа?

ответ

2

Неспособность сформировать указатель на функцию ограничения по ограничению, даже в неоценимом контексте, является обломком. Однако существует временное решение, которое является жизнеспособным до тех пор, пока вы можете потребовать, чтобы лямбда-ампер-ограничение было cpu, ограничение по типу. В таком случае вы можете отключить ограничение на усилитель, образуя указатель на ограниченную cpu функцию-член, которую вы можете допросить дальше.

См следующее доказательство правильности концепции:

#include <type_traits> 

template <typename R, typename F, typename... A> 
auto get_R(R (F::*)(A...) const) -> R 
{} 

template <typename L> 
struct lambda_traits 
{ 
    using ret_type = decltype(get_R(&L::operator())); 
}; 

int main() 
{ 
    auto lambda_1 = [](int) restrict(cpu,amp) -> void {}; 
    auto lambda_2 = [](int) restrict(cpu,amp) -> int { return 0; }; 

    // Test: 
    static_assert(std::is_same<lambda_traits<decltype(lambda_1)>::ret_type, void>::value, "Failed 1."); 
    static_assert(std::is_same<lambda_traits<decltype(lambda_2)>::ret_type, int>::value, "Failed 2."); 
} 

Надежда, что помогает!

+0

Ммм аккуратный, это действительно жизнеспособная работа. Я был обеспокоен тем, что не смог бы использовать это, чтобы специализировать шаблонные 'ограниченные (amp)' функции, поскольку я ожидал, что это отбросит часть 'restrict (cpu)'. Как ни странно, ограничение cpu, похоже, цепляется за определение лямбда (хотя оно не является вызываемым) даже внутри закрытого ограниченного диапазона «amp». Я не уверен, что это ошибка с реализацией или что-то, но она немного сломана ... В любом случае, спасибо за обнаружение этого, и я не могу думать о каких-либо серьезных недостатках, ограничение cpu' на лямбда. – geoff3jones

+0

Да, ограничения не являются (неофициально) «сброшены при пересечении границы ограничения». В противном случае вы не смогли бы вызвать parallel_for_each с ограничением amp-lambda из контекста, ограниченного cpu. –

+0

Ах, конечно, это хороший момент, я думаю, что меня путают, рисуя параллели с перегрузкой функции члена на 'restric'. Приветствия за помощь и идеи! – geoff3jones

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