在关于可恢复功能的文章中,在关于限制的部分中列出了三个限制:
- 可恢复的函数不能使用可变数量的参数.对于需要varargs的情况,可以将参数展开放在一个函数中,该函数在执行参数展开后调用可恢复函数.
- 可恢复功能的返回类型必须是
future<T>或shared_future<T>.对T的限制std::future由此提议定义,但T必须是可复制或可移动的类型,或'void'.还必须能够构造一个T没有参数的变量; 也就是说,如果它是类类型,它必须具有可访问(隐式或显式)默认构造函数.- Await表达式可能不会出现在异常处理程序的主体内,并且在执行线程持有任何类型的锁时不应执行.
这种限制背后必然有一个原因,由于我对并发性缺乏了解,我无法推断出原因是什么.有人可以为我这个话题加油吗?
这个限制是指C风格的可变参数函数还是C++ 11可变参数模板?
va_*吗?在这两种情况下,我认为编译器可以足够聪明地推断出要使用的功能.
我理解返回a std::future或者背后的原因std::shared_future,但我猜测可用类型背后的限制的原因与期货可以使用的类型有关.
因此,本文建议使用两个新的关键字(可恢复和等待)来扩展语言,这两个关键字提供可恢复函数的行为,但最终它信任现有的构造,以在函数和调用者之间传递可恢复函数的返回值.
为什么不为返回值提出某种语言扩展呢?可能(可能)释放对默认可构造和可复制/可移动类型的限制,并修复返回类型和返回类型之间的分配:
因此应该注意到,函数从外部(调用者)和内部观察到的行为之间存在不对称性:外部透视图是函数
future<T>在第一个暂停点返回类型的值,而内部透视图是函数T通过return语句返回一个type类型的值(...)
我想在捕获异常时等待某些东西没有任何意义,但我对锁定线程的限制没有任何线索.
我很确定所有这些限制都与可恢复函数的上下文必须“保存”和“恢复”这一事实有关 - 我希望该机制将创建一个临时的“堆栈副本”或类似的东西。所以:
可变数量的参数
这确实意味着使用va_arg功能的事情 - 不是因为涉及宏,而是因为外部代理不可能知道实际参数的数量 - 对于printf,您必须读取格式字符串,对于其他一些,最后一个标记为NULL。那么需要保存多少上下文呢?
锁定的线程
所以我们刚刚说过“我们不希望这个线程被中断”,然后我们说“现在让我们运行其他东西”。这就像在走进浴室时说“拜托,在任何情况下都不能打扰我洗澡”,同时说“你能在 2 分钟内给我打电话吗……”——假设洗澡时间超过 2 分钟分钟,其中之一将是不真实的。
默认可构造
我很确定这里的逻辑是,如果要构造的返回值必须将参数传递给构造函数,那么整个概念就会变得非常复杂。你会如何描述这样的事情?在暂停状态下,您还必须“坚持”这些论点。再次,使上下文的保存变得更加复杂。