Специализированные шаблоны на 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
Есть ли другой способ опрашивать типы в лямбда-выражениях или же способ снять ограничение с лямбда-типа?
1 ответ
Невозможность сформировать указатель на функцию, ограниченную усилителем, даже в неоцененном контексте, является обломом. Однако существует обходной путь, который является жизнеспособным, если вы можете требовать, чтобы лямбды с ограничением по амперу были ограничены по процессору и по амперу. В таком случае вы можете отменить ограничение amp, сформировав указатель на функцию-член с ограничением 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.");
}
Надеюсь, это поможет!