When you write:
function<int(int)> idInt = [](int &i) {return i;};
then you say idInt can wrap the function, a closure that can be called using the int argument. But this is not so in the case of [](int &i) {return i;}; , because you cannot call it an integral literal, as here:
auto fn = [](int &i) {return i;}; fn(1);
you can fix this by changing the signature to use the rvalue or const & link:
std::function<int(int)> idInt1 = []( int &&i) {return i;}; std::function<int(int)> idInt2 = []( const int &i) {return i;};
source share