explicit instantiation with default template/function arguments
Solution 1:
The problem is that you did not keep the signature consistent. The declaration in the header accepts by rvalue reference, the implementation file by value, and the instantiation is for a function with absolutely no parameters (a default argument doesn't mean a function has no parameters).
You need to stick to the same signature everywhere.
So either
#include <functional>
template<typename T = std::function<void(int,int)>> void foo (T &&t = [](int,int)->void{});
//in .cpp
template<typename T> void foo (T&&){}
template void foo<>(std::function<void(int,int)>&&);
Or
#include <functional>
template<typename T = std::function<void(int,int)>> void foo (T t = [](int,int)->void{});
//in .cpp
template<typename T> void foo (T){}
template void foo<>(std::function<void(int,int)>);