With "define" I think you can not do it, but with "variadic templates" it is possible, although it is somewhat complicated.
#include <iostream>
using namespace std;
void adicionar(int i)
{
cout << "* adicionando " << i << '\n';
}
void adicionarTodos()
{
}
template <typename A1, typename ... As >
void adicionarTodos(A1 a1, As... as)
{
adicionar(a1);
adicionarTodos(as...);
}
int main()
{
adicionarTodos(1);
adicionarTodos(2, 3);
adicionarTodos(4, 5, 6);
}
Result:
* adicionando 1
* adicionando 2
* adicionando 3
* adicionando 4
* adicionando 5
* adicionando 6
Added after: I think the above solution does not actually answer the question asked. I researched a bit more, and based on this response from SOen I've created another solution, which I think is more appropriate to answer:
#include <iostream>
using namespace std;
struct X1 { enum { i = 1 }; };
struct X2 { enum { i = 2 }; };
struct X3 { enum { i = 3 }; };
struct X4 { enum { i = 4 }; };
struct X5 { enum { i = 5 }; };
struct X6 { enum { i = 6 }; };
// condicao de parada do template
template <int i=0> void adicionarTodos() { }
template <typename A1, typename ... As>
void adicionarTodos()
{
cout << "* adicionando " << A1::i << '\n';
adicionarTodos<As...>();
}
int main()
{
adicionarTodos<X1>();
adicionarTodos<X2,X3>();
adicionarTodos<X4,X5,X6>();
}