https://github.com/google/oboe/blob/e3e93e307456a388a84a6e0d96f9adb240f5918d/apps/fxlab/app/src/main/cpp/native-lib.cpp#L93
std::visit([id](auto &&stack) {
std::function<void(decltype(stack.getType()), decltype(stack.getType()))> f;
int i = 0;
std::apply([id, &f, &i](auto &&... args) mutable {
((f = (i++ == id) ?
args.template buildDefaultEffect<decltype(stack.getType())>() : f), ...);
}, EffectsTuple);
stack.addEffect(std::move(f));
}, enginePtr->functionList);
std::visit将lambda应用于向量functionList
。lambda,将其内部的lambda应用于EffectsTuple
。
然而,我很难理解
((f = (i++ == id) ?
args.template buildDefaultEffect<decltype(stack.getType())>() : f), ...);
最外层的()
做什么?第二个自变量...
是什么?args.template
是什么意思?
((f = (i++ == id) ?
args.template buildDefaultEffect<defaultEffect<decltype(stack.getType())>() : f), ...);
这是一个逗号折叠执行包扩展。这是一种遍历元组中非统一类型元素的方法。
如果你可以迭代一组非均匀元素:
int i=0;
for...(auto& arg:args...){
if (i!=id){
++i;
continue;
}
f=arg.template buildDefaultEffect<defaultEffect<decltype(stack.getType())>();
break;
}
这是他们想要编写的代码。但他们做不到。
因此,他们使用逗号折叠执行来为args中的每个arg生成与上面循环正文等效的内容。
并且在";什么都不做";他们做CCD_ 6。
我自己会做:
((i++ == id) ?
f=args.template buildDefaultEffect<defaultEffect<decltype(stack.getType())>() : nullptr), ...);
这既更清晰又更有效。
或者,foreach_arg
是一个有用的写入替代方案。或者制作一个n大小的函数指针数组,每个指针做一个循环体,只运行一个。
第二个参数是什么。。。?
(foo(args), ...)
是一个折叠表达式,使用逗号运算符,相当于(foo(arg0), foo(arg1), .., foo(argn))
args.template是什么意思?
template
用于消除依赖类型的<
的含义歧义
否则,它将被解析为
(args.buildDefaultEffect < decltype(stack.getType())) > ()
。
查看在哪里以及为什么要输入模板和类型名称关键字。
...
是逗号运算符的右折叠。该代码本质上是为具有请求id的args
变量调用buildDefaultEffect
函数,将返回值分配给f
,然后将f
添加到具有stack.addEffect
的堆栈中。
基本上,代码扩展到类似的东西
(f = f, f = f, /*i == id*/ f = args.buildDefaultEffect(stack.getType()), f = f, f = f);
stack.addEffect(f);