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

问题描述 投票:0回答:2

假设三个对象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时才有效。

是否有一种优雅的零成本抽象方法,可以针对不同的类型和非const函数立即抽象出免费的相同方法调用?

这最好用于涉及value的任意语句。

c++ abstraction code-duplication
2个回答
2
投票

您可以在parameter pack的帮助下将它们包装到功能模板中。

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

然后

call_bar(bar, a, b, c);

LIVE


0
投票

我用聪明的宏自己为多达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上确实可以正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.