I’m trying to understand why this snippet fails:
#include <iostream>
using namespace std;
template <typename Lambda>
struct Handler
{
bool _isCompleted;
bool isCompleted() { return _isCompleted; }
Lambda _l;
Handler(Lambda&& l) : _l(l) {}
void call() { _l(this); }
};
int main()
{
auto l1 = new Handler( [&](decltype(l1) obj )->
{
obj->_isCompleted = true;
cout << " is completed?" << obj->isCompleted() << endl;
});
l1->call();
};
g++ 4.5 fails with:
test.cpp: In function ‘int main()’:
test.cpp:21:17: error: expected type-specifier before ‘Handler’
test.cpp:21:17: error: expected ‘,’ or ‘;’ before ‘Handler’
test.cpp:25:2: error: expected primary-expression before ‘)’ token
test.cpp:25:2: error: expected ‘;’ before ‘)’ token
test.cpp:26:7: error: request for member ‘call’ in ‘* l1’, which is of non-class type ‘int’
my understanding is that auto l1 should resolve to Handler<lambdaType>* and lambdaType should have a public function signature void( Handler<LambdaType>*). I don’t see any blatantly wrong with the above example (you know, besides the ugliness and the slightly pathological cyclic dependency between the lambda and the handler type)
One problem is, as @Cat said, that template argument deduction just does not work for constructor calls. You always need to specify the template argument.
The other problem is nicely illustrated by Clang with the following snippet:
Output:
Obligatory standard quote:
§7.1.6.4 [dcl.spec.auto] p3