P99_FOR в C ++ 11

Я использую P99_FOR макрос, определенный в P99 в моем коде C99, чтобы перебрать VA_ARGS. Работает отлично.

P99_FOR(NAME, N, OP, FUNC,...)

Теперь я хочу перейти на C ++ 11, и мне было интересно, есть ли макрос, похожий на P99_FOR.

Вот мой код в C99:

#ifndef __cplusplus

#include "p99/p99.h"
#undef P00_VASSIGN
#define P00_VASSIGN(NAME, X, I) NAME[I] = X

#define FOREACH(x, y, z, u, ...) P99_FOR(x, y, z, u, __VA_ARGS__);

#else

#define FOREACH(x, y, z, u, ...) ???  // C++ equivalent

#endif

#define set_OCTET_STRING(type, numParams, ...) { \
FOREACH(type, numParams, P00_SEP, P00_VASSIGN, __VA_ARGS__); \
}

Например set_OCTET_STRING(myVar->speed, 3, 34, 10, 11) будет расширяться до:

myVar->speed[0] = 34; myVar->speed[1] = 10; myVar->speed[2] = 11;

2

Решение

У вас есть несколько способов пойти. Если вы можете получить итераторы для ваших данных, вы можете использовать std::accumulate.

Пример взят из документации:

#include <iostream>
#include <vector>
#include <numeric>
#include <string>
#include <functional>

int main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int sum = std::accumulate(v.begin(), v.end(), 0);

int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());

[...]
}

Если ваши аргументы не повторяемы, например, Отдельные переменные в стеке, вы должны построить его самостоятельно, используя шаблоны variardic:

#include <vector>
#include <numeric>
#include <functional>
#include <iostream>

template <class Func, class ReturnType, class... Args>
ReturnType P99_FOR(Func op, ReturnType initialValue, Args... args) {
std::vector<ReturnType> values{args...};
return std::accumulate(values.begin(), values.end(), initialValue, op);
}

template <class... Tags>
struct TagList {};
int main(int argc, char* argv[])
{
int a = 4, b = 10, c = 21;

// You can use predefined binary functions, that come in the <functional> header
std::cout << "Sum:" << P99_FOR(std::plus<int>(), 0, a, b, c) << std::endl;
std::cout << "Product:" << P99_FOR(std::multiplies<int>(), 1, a, b, c) << std::endl;

// You can also define your own operation inplace with lambdas
std::cout << "Lambda Sum:" << P99_FOR([](int left, int right){ return left + right;}, 0, a, b, c) << std::endl;

return 0;
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]