I have in essence the following code:
typedef std::function<void ()> fnGlobalChangeEvent;
typedef std::vector<fnGlobalChangeEvent> GlobalTriggers;
inline void ExecuteGlobal(fnGlobalChangeEvent ev)
{
ev();
}
GlobalTriggers triggers;
std::for_each(triggers.begin(), triggers.end(), std::bind(&ExecuteGlobal, _1));
The use of ExecuteGlobal feels totally redundant here, but I can't find the right syntax to drop out the call.
std::for_each(triggers.begin(), triggers.end(), ExecuteGlobal(_1));
std::for_each(triggers.begin(), triggers.end(), std::bind(_1));
Both fail to compile.
There is also a more complex case:
typedef std::function<void (Zot&)> fnChangeEvent;
typedef std::vector<fnChangeEvent> Triggers;
inline void Execute(fnChangeEvent ev, Zot& zot)
{
ev(zot);
}
Triggers triggers;
std::for_each(triggers.begin(), triggers.end(), std::bind(&Execute, _1, zot));
Is it possible to do without the helper functions in these cases?
Sure, a lambda:
std::for_each(
triggers.begin(), triggers.end(),
[](fnChangeEvent ev) { ev(); }
);
std::for_each(
triggers.begin(), triggers.end(),
[&zot](fnChangeEvent ev) { ev(zot); }
);
Or even better, range for:
for (auto ev : triggers) {
ev();
}
// well, I think you can figure out the second one
Why don't you use lambda as:
std::for_each(triggers.begin(),
triggers.end(),
[&](fnChangeEvent & e)
{
e(zot);
});
Or using range-based for loop as:
for (auto& e : triggers) { e(zot); }
which looks more concise and cleaner.
Here's something I just thought up, tell me if it's something like what you're looking for:
template<typename IT, typename ...Args>
void call_each(IT begin_, IT end_, Args&&... args)
{
for (auto i = begin_; i!=end_; ++i)
(*i)(std::forward<Args>(args)...);
}
Then you could use it like this:
call_each(triggers.begin(), triggers.end());
And for functions with arguments:
call_each(triggers.begin(), triggers.end(), zot);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With