It would be nice if I could do the following:
template <class RT, class... PT>
class Event
{
...
void operator()(PT... args)
{
std::for_each(
l.begin(), l.end(), [args...](Handler *p) { (*p)(args...); }
);
}
...
};
Unfortunately I couldn’t make it compile with g++ 4.7.2 (-std=c++0x):
evtempl.hh: In member function ‘void elt::Event::operator()(PT …)’:
evtempl.hh:75:54: error: expected ‘,’ before ‘…’ token
evtempl.hh:75:54: error: expected identifier before ‘…’ token
evtempl.hh:75:57: error: parameter packs not expanded with ‘…’:
evtempl.hh:75:57: note: ‘args’
evtempl.hh: In lambda function:
evtempl.hh:76:26: error: expansion pattern ‘args’ contains no argument packs
evtempl.hh: In instantiation of ‘void elt::Event::operator()(PT …) [with RT = void; PT = {int}]’:
testevtempl.cc:28:9: required from here
evtempl.hh:74:9: error: using invalid field ‘elt::Event::operator()(PT …)::::Handler*)>::__args’
evtempl.hh: In instantiation of ‘void elt::Event::operator()(PT …) [with RT = void; PT = {int, const char*}]’:
testevtempl.cc:29:20: required from here
evtempl.hh:74:9: error: using invalid field ‘elt::Event::operator()(PT …)::::Handler*)>::__args’
instead, I have to change that lambda to the old, mundane syntax:
for (itr = l.begin(); itr != l.end(); ++itr)
(*(*itr))(args...);
This one compiles and works fine.
I wonder why the lambda syntax doesn’t work.
- Did I do something wrong or miss something?
- Is such thing outlawed in the c++11 standard?
- or, this is allowed by the standard, but it’s
a problem of the current compiler?
I tried
[=](Handler *p) { (*p)(args...); }
it gives the same error as if you did:
[args](Handler *p) { (*p)(args...); }
complaining parameter packs not expanded
It’s a bug in gcc. See [c++0x]lambdas and variadic templates don’t work together or perhaps [C++11] Pack expansion fails in lambda expressions.