Абстракция нулевой стоимости для выполнения одного и того же оператора на нескольких объектах - PullRequest
0 голосов
/ 04 ноября 2019

Допустим три объекта A a, B b и C c. У всех трех есть метод с подписью void foo(Bar& bar).

Иногда мне нужно написать следующий код:

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

Теперь это много дублирования кода, особенно когда выражение становится длиннее.

До сих пор я придумал

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

Но это работает, только если a, b и c относятся к одному типу, а fooconst.

Существует ли элегантная абстракция с нулевой стоимостью для одновременного абстрагирования бесплатных идентичных вызовов методов для различных типов и неконстантных функций?

Это предпочтительно будет работать напроизвольные заявления с участием value.

Ответы [ 2 ]

3 голосов
/ 04 ноября 2019

Вы можете заключить их в шаблон функции с помощью пакета параметров .

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

затем

call_bar(bar, a, b, c);

LIVE

0 голосов
/ 04 ноября 2019

Я сам решил это для 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, хотя.

...