我正在尝试在我的C ++代码中实现一个易于使用的async/await
模式,我有一种方法可以让我发现它非常简单易用。但是,由于我使用的是宏,因此在对外来代码的弱点方面也会付出代价。
这是一个想法:
async
函数使用的变量。在async
函数的主体内部,我使用宏来实现成员entrypoint
上的一个开关,用于跟踪恢复执行函数时的跳转位置:< / p>
switch(this->entrypoint)
{
// All the async code occurs here, like:
await(this->foo = bar());
std :: cout << this->foo << std :: endl;
await(this->foo2 = bar2());
std :: cout << this->foo2 << std :: endl;
}
await(assignment)
宏实际上定义了表单中的内容:
this->entrypoint = (some value x);
return;
case x:
现在,这显然不如我们可以拥有的成熟async function
那么紧凑,例如,在Javascript中,但它足以满足我的需求。这也防止了嵌套开关(我很少使用它),你不能在本地定义变量,除非你以某种方式将它们包装在{ /*..*/ }
中。但是我得到了一种使用同步样式进行异步操作的超级紧凑方式。
备注:这个策略的缺点和缺点对我来说非常清楚,这不是我的问题,我只是添加了这个来帮助理解我需要的东西。
以上编译并运行良好。但是,我遇到了一个严重的问题:在await
宏中,我需要生成一些在x
语句中使用的唯一值case
。到目前为止,我正在使用__LINE__
来完成它,它可以很好地工作并防止碰撞用于大多数实际目的。但是,当您在同一行上写两个await
语句时会发生什么?
所以我想知道:有没有比使用__LINE__
唯一标识对宏的调用更好的方法,这样每当我从代码中的两个不同位置调用相同的宏时,我会得到不同的扩展值?< / p>
答案 0 :(得分:3)
类型系统提供了创建编译时变量的方法;但是,它没有提供任何在调用之间维持状态的方法。
但是,使用here描述的方法,您可以通过检查已创建的哪些函数可以在模板系统中创建constexpr
计数器,这可能对您有用;然而,这个系统依赖于gcc生成函数的方式的一些承诺,并且可能在将来不起作用,它目前在clang上失败。
因为这里的所有内容都在编译时运行(主要在类型系统中),所以你既可以使用switch语句中的值,也可以在运行时使用(几乎)零开销。
This post描述了一种完全用宏构建编译时间计数器的方法;但是,要使值constexpr
创建新函数,只能从函数外部递增。
__COUNTER__
分机号预处理器的标准没有提供请求唯一值的方法;但是,如__COUNTER__
评论中提到的#define aswitch(x) \
int position_counter=0;
if(this->entrypoint==position_counter++)
#define await(x) \
this->entrypoint=position_counter; \
}else if(this->entrypoint==position_counter++){
aswitch(this->entrypoint)
{
await(bar());
std :: cout << this->foo << std :: endl;
await(bar2());
std :: cout << this->foo2 << std :: endl;
}
将执行请求的任务。 GCC has an extension和Visual Studio也支持此功能。
一个简单的修复(虽然我对你的实现知之甚少)可能是删除switch语句,而不是链接if else-if集。
static struct addr_map
{
__u32 paddr,vaddr;
ssize_t size;
}*lp;