随着VisualStudio 2015 RC的发布,我们希望提供关于VisualC++中可恢复函数支持的更新的内容。自 上次 ,我们对跟踪 最新提案 (除了可恢复的u特征和可恢复的u句柄被称为coroutineu traits和coroutineu handle,如前面的建议所示)。请注意,这仍然是一个实验性功能,目前仅适用于x64目标,还需要一个opt-in开关(/await)来使用它。
有什么新鲜事吗?
自动类型扣除
我们为可恢复函数启用自动类型推断
#包括
#包括
汽车 你好(){
对于 ( 汽车 中国: “你好,worldn” )
产量 中国;
}
内景 主(){
对于 ( 汽车 ch:你好())
标准::cout<
} 类型扣除规则如下: 如果函数返回类型为auto或declspec(auto),且未指定尾部返回类型,则可恢复函数的返回类型推断如下:
- 如果存在yield语句和await表达式或await for语句,则返回类型为 std::实验::异步u流
,其中T是从收益率声明中推导出来的 - 否则,如果函数中存在await表达式或await for语句,则返回类型为 标准::实验::任务
其中T类型是从return语句推导出来的 - 否则,如果函数中存在yield语句,则返回类型为 标准::实验::发生器
在VisualStudio2015RC中,我们只提供std::experimental::generator
实验关键词
实验关键字“await”和“yield”可用/await开关。yield是一个上下文敏感的关键字,如果后跟“(”,将被解释为标识符。这个规则将来可能会改变。
可选成员函数
-
setu exception成员函数现在是可选的
如果coroutineu promise没有此函数,异常将正常地从可恢复函数中传播出去(注意,与调用者同步执行的生成器不需要提供set(异常)
-
setu result成员函数现在是可选的
如果不存在,则不能在可恢复函数的主体中使用await(生成器没有在其promise中定义此成员函数,因此在生成器中使用await的错误将在编译时被捕获)
对初始成员函数、最终成员函数和产生成员函数的要求进行了简化。它们不再需要返回等待类型。现在它们返回true(如果需要挂起)或false。yieldu value成员函数还可以具有void返回类型,该类型被解释为后跟无条件挂起。
下面是一个激励示例,当yieldu值可能需要返回一个布尔值来控制是否需要暂停。
递推脉冲发生器< 内景 >漫游(节点*根){
如果 (根目录){
产量 行走(根->左); //调用一个超载,需要一个发电机
产量 根->值; //调用接受int的重载
产量 行走(根->右); //调用一个超载,需要一个发电机
}
}
上面的例子是使用递归的生成程序(不在建议中,但可以使用可恢复函数实现)。在这种情况下,对yield walk(…)的递归调用可能不会产生任何值(如果树为空),在这种情况下,yieldu value必须返回false。因此,以递归u生成器作为参数的yield u值重载必须返回bool。接受int的u值重载可以是void类型,因为它总是返回值。
取消机制的变化
与在promise中使用cancellationu requested()成员函数来指示需要在下一次恢复时取消可恢复的函数不同,在coroutineu句柄中添加了一个显式成员函数destroy()。可以调用destroy()成员函数来强制恢复协同程序,使其进入取消路径。
此更改主要影响library writer,因为它简化了生成器和任务类型的编写。
已知缺陷/限制:
- 无法在可恢复函数的签名中使用Windows运行时(WinRT)类型,并且可恢复函数不能是WinRT类中的成员函数(这是固定的,但没有及时为RC发布)
- 如果return语句出现在可恢复函数中,在看到等待表达式或yield语句之前,我们可能会给出错误的诊断(解决方法:重新构造代码,使第一次返回发生在yield或await之后
- 如果使用/ZI标志编译代码(编辑并继续调试),则使用可恢复函数编译代码可能会导致编译错误或错误的codegen
- 调试时,可恢复函数的参数可能不可见
抱歉重复声明。我们知道有漏洞,我们继续努力。这仍然是一个实验特性,目的是从您那里获得设计反馈。我们期待着您的来信。
Gor Nishanov和Raman Sharma