【问题标题】:Specialising templates on C++AMP restricted lambdas专门针对 C++AMP 受限 lambda 的模板
【发布时间】:2013-12-19 17:08:24
【问题描述】:

使用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&lt;decltype(myLambda)&gt; 一起使用,但这就是我自鸣得意的编码结束的地方,因为如果我的 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 类型的限制?

【问题讨论】:

    标签: visual-c++ lambda template-specialization c++-amp restrict-qualifier


    【解决方案1】:

    即使在未评估的上下文中,也无法形成指向受 amp 限制的函数的指针,这真是令人遗憾。但是,有一种解决方法,只要您可以要求 amp-restricted lambda 为 cpu,amp-restricted,这是可行的。在这种情况下,您可以抛弃 amp-restriction,形成一个指向 cpu-restricted 成员函数的指针——您可以进一步询问。

    请参阅以下概念验证:

    #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.");
    }
    

    希望有帮助!

    【讨论】:

    • 嗯,很好,这确实是一个可行的解决方法。我担心我将无法使用它来专门模板化 restrict(amp) 函数,因为我希望这会丢弃 restrict(cpu) 部分。奇怪的是,即使在封闭的amp 受限范围内,cpu 限制似乎也坚持 lambda 定义(尽管它不可​​调用)。我不确定这是实现的错误还是什么,但感觉有点坏了...无论哪种方式都感谢您发现它,而且我想不出任何主要的缺点来要求额外的cpu对 lambda 的限制。
    • 是的,限制不会(非正式地)“在跨越限制边界时被删除”。否则,您将无法从受 CPU 限制的上下文中使用受放大器限制的 lambda 调用 parallel_for_each。
    • 啊,这当然是一个好点,我想我被restric 上的成员函数重载类比弄糊涂了。为帮助和想法干杯!
    猜你喜欢
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多