Search code examples
c++templatesexplicit-instantiation

explicit instantiation with default template/function arguments


I'm trying to explicitly instantiate a templated function that has a default template argument as well as a default value for the corresponding parameter but I can't find the right syntax. What I'm trying is the following:

// in .hpp
template<typename T = std::function<void(int,int)>> void foo (T &&t = [](int,int)->void{});
//in .cpp
template<typename T> void foo (T t){...}
template void foo<>();

But I just get an error saying foo<> does not match any template declaration. Is there any way to use default type and argument values while still being able to do an explicit instantiation? The only other option for me would be to either define the whole function in the header which I would prefer no to do or to give up on having default values.


Solution

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