The do
/while(false)
thing is a way to protect the macro from accidents when you use it in an if
statement.
You can replace the macro with a nice function template:
template <typename Container, typename FPtr>
void ITERATE_AND_CALL(Container& container, FPtr callable)
{
for (auto& v : container)
(v.*callable)();
}
This is almost a drop-in replacement, except you can't just pass the name of a function… you have to use the address-of operator:
struct Foo
{
void func() {}
};
int main()
{
std::vector<Foo> v(3);
ITERATE_AND_CALL(v, &Foo::func);
}
So &Foo::func
rather than just func
. There's no way around that.
If you can modify the callsites further, though, there are better ways of doing this that don't restrict you to function pointers and no-arg callbacks:
template <typename Container, typename Callable>
void IterateAndCall(Container& container, Callable func)
{
for (auto& v : container)
func(v);
}
Now your func
can be a lambda or any other thing that binds whatever you like, e.g.
std::vector<int> vecOfFoos{1,2,3};
IterateAndCall(vecOfFoos, [](const int v) { std::cout << v; });
This is pretty much just a shorter, re-invented version of std::for_each
. You should probably just use std::for_each
if you get to this point… or simply write out the loop.