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)>);