I have some trouble to return a reference from a lambda. This code works :
std::function<int*(int*)> funct;
funct = [](int *i){
++*i;
return i;
};
int j = 0;
std::cout << *funct(&j) << j;
Output : 1 1
But not this one :
std::function<int&(int&)> funct;
funct = [](int &i){
++i;
return i;
};
int j = 0;
std::cout << funct(j) << j;
Building error :
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\type_traits:1441: error: C2440: 'return': cannot convert from 'int' to 'int &'
Why is this happening?
The lambda deduces the return type as if specified with auto
. auto ret = i;
would deduce ret
to be an int
.
One solution is to explicitly state the return type of the lambda:
funct = [](int &i) -> int& {
++i;
return i;
};
As mentioned in the comments another way is
funct = [](int &i) -> decltype(auto) {
++i;
return i;
};
which essentially tells the compiler not to do any deduction and to just use the type as if decltype
had been used on the return expression.
If you are curious about the exact rules check the documentation which also has a section on auto
and a bit on decltype(auto)
.