在多个对象上执行同一语句的零成本抽象

Zero cost abstraction for executing same statement on multiple objects

本文关键字:零成 抽象 语句 对象 执行      更新时间:2023-10-16

假设三个对象A aB bC c。三者都有一个签名为void foo(Bar& bar)的方法。

有时我需要写以下代码:

a.foo(bar);
b.foo(bar);
c.foo(bar);

现在有很多代码重复,尤其是当表达式变长时。

到目前为止,我已经提出了

foreach (const auto& value : { a, b, c}) value.foo(bar);

但只有当abc是同一类型,并且fooconst时,这才有效。

对于不同的类型和非常量函数,是否有一个优雅的零成本抽象来同时抽象免费的相同方法调用

这最好适用于涉及CCD_ 10的任意语句。

您可以在参数包的帮助下将它们封装到一个函数模板中。

template <typename... T>
void call_bar(Bar& bar, const T&... t) {
(t.foo(bar), ...);
}

然后

call_bar(bar, a, b, c);

实时

我自己用聪明的宏解决了多达5个参数:

// Does not work on MSVC, since they use a different preprocessor algorithm than clang and gcc.
// Use like this:
//   foreach(const &, myFoo1, myFoo2, myFoo3, _.foo());
//   foreach(&&, a, b, c, sum += _);
#define _GET_FOR_EACH_MACRO(_0, _1, _2, _3, _4, _5, _6, NAME, ...) 
NAME
#define _FOR_EACH1(refMod, _1, expr) 
{ auto refMod _ = _1; (expr); };
#define _FOR_EACH2(refMod, _1, _2, expr) 
{ auto refMod _ = _1; (expr); }; 
_FOR_EACH1(refMod, _2, expr)
#define _FOR_EACH3(refMod, _1, _2, _3, expr) 
{ auto refMod _ = _1; (expr); }; 
_FOR_EACH2(refMod, _2, _3, expr)
#define _FOR_EACH4(refMod, _1, _2, _3, _4, expr) 
{ auto refMod _ = _1; (expr); }; 
_FOR_EACH3(refMod, _2, _3, _4, expr)
#define _FOR_EACH5(refMod, _1, _2, _3, _4, _5, expr) 
{ auto refMod _ = _1; (expr); }; 
_FOR_EACH4(refMod, _2, _3, _4, _5, expr)
#define foreach(...) _GET_FOR_EACH_MACRO(__VA_ARGS__, _FOR_EACH5, _FOR_EACH4, _FOR_EACH3, _FOR_EACH2, _FOR_EACH1)(__VA_ARGS__)

出于某种原因,这在MSVC 2019中不起作用,因为__VAR_ARG__是作为单个参数传递给其他宏的,而不是作为多个参数。它确实在Clang和GCC上运行良好。