5.扩展的lambda不能在函数本地的类中定义。 例:
6.扩展lambda的封闭函数不能推导出返回类型。 例:
7.<code>__host__</code> <code>__device__</code>扩展lambdas不能是通用lambdas。例:
8.如果封闭函数是函数模板或成员函数模板的实例,并且/或者函数是类模板的成员,则模板必须满足以下约束条件:
该模板必须至多有一个可变参数,并且必须在模板参数列表中最后列出。
模板参数必须命名。
模板实例化参数类型不能涉及函数本地的类型(扩展lambdas的闭包类型除外),或者是私有或受保护的类成员。
例子:
9.使用Visual Studio 2013及更高版本的Visual Studio主机编译器时,封闭函数必须具有外部链接。 限制是存在的,因为该主机编译器不支持将非外部链接函数的地址用作模板参数,这是CUDA编译器转换所需的,以支持扩展lambda表达式。
10.扩展lambda对捕获的变量有以下限制:
变量只能通过值来捕获。
数组类型的变量不能被捕获。
无法捕获作为可变参数包的元素的函数参数。
捕获的变量的类型不能涉及函数本地的类型(除了扩展lambdas的闭包类型),或者是私有类或受保护的类成员。
对于<code>__host__</code> <code>__device__</code>扩展lambda,在lambda表达式的operator()的return或参数类型中使用的类型不能涉及函数本地的类型(除了扩展lambdas的闭包类型),或者是私有或受保护的类成员。
<code>__host__</code> <code>__device__</code>扩展lambdas不支持初始捕获。 initcapture支持<code>__device__</code>扩展lambda表达式,除非initcapture类型为std :: initializer_list。
11.解析函数时,CUDA编译器为该函数中的每个扩展lambda分配一个计数器值。 该计数器值用于传递给主机编译器的替换命名类型。 因此,函数中是否定义了扩展lambda是不应该依赖于<code>__CUDA_ARCH__</code>的特定值,或者是<code>__CUDA_ARCH__</code>未定义。
12.如上所述,CUDA编译器用命名空间范围中定义的占位符类型替换主机函数中定义的<code>__device__</code>扩展lambda。 此占位符类型未定义与原始lambda声明等效的operator()函数。 由于主机编译器处理的代码与CUDA编译器处理的输入代码在语义上不同,因此尝试确定operator()函数的返回类型或参数类型可能会在主机代码中错误地工作。 但是,可以在设备代码中反省operator()函数的返回类型或参数类型。 请注意,此限制不适用于<code>__host__</code> <code>__device__</code>扩展lambdas。
13.如果由扩展lambda表示的函子对象从主机传递到设备代码(例如,作为<code>__global__</code>函数的参数),则表达式捕获变量的lambda表达式的任何表达式都必须保持不变,而不管<code>__CUDA_ARCH__</code> 宏定义,宏是否有特定的值。 这种限制的出现是因为lambda的闭包类布局取决于编译器在处理lambda表达式时遇到的捕获变量的顺序; 如果封装类布局在设备和主机编译中不同,程序可能会错误地执行。
如前所述,CUDA编译器用发送到主机编译器的代码中的占位符类型实例替换扩展的__device__ lambda表达式。 此占位符类型未在主机代码中定义指针函数转换运算符,但转换运算符在设备代码中提供。 请注意,此限制不适用于__host__ __device__扩展lambdas。
CUDA编译器将为1-10中描述的一些情况生成编译器诊断; 对于情况11-14,将不会生成诊断信息,但主机编译器可能无法编译生成的代码。
