使用this question(以及其他一些人)的洞察力,我能够编写以下内容来询问正常的lambda函数类型信息(即返回类型,参数计数等)
// 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)>
一起使用,但这就是我的自以为是的编码结束的地方,因为如果我的lambda是对gpu进行放大限制的,即
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
有另一种方法可以查询lambdas中的类型,还是有办法去除lambda类型的限制?
答案 0 :(得分:2)
即使在未评估的环境中,也无法形成指向放大器限制功能的指针,这是一个无赖。但是有一个解决方法,只要您可以要求放大器限制的lambda为 cpu,amp-restricted ,这是可行的。在这种情况下,你可以抛弃放大器限制,形成一个指向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.");
}
希望有所帮助!