Search code examples
c++templatesc++17variadic-templates

Variadic template function arguments not accepted


The following code won't build, any feedback on the cause would be appreciated.

void bar(std::string str, int& a, int& b)
{
}

template<typename T, typename ... Args>
void foo(std::function<void(T, Args...)> fcn, Args ... args)
{
    // Some code that calls fcn
}

void run()
{
    int a = 3;
    int b = 5;
    foo<std::string, int&, int&>(bar, a, b);
}

It is a modified implementation of the first solution proposed in this SO answer.

The IDE gives the following error on the line calling foo:

C++ template<class T, class... Args> void foo(std::function<void (T, Args...)> fcn, Args ...args)

no instance of function template "foo" matches the argument list
argument types are:
(void (std::string str, int &a, int &b), int, int)

Tested separately, it seems like passing a fcn argument with template arguments are fine. The issue seems to be with passing a function argument where the function can accept variadic template arguments.


Solution

    • & when I removed it, there was no error
    #include <iostream>
    #include <functional> 
    
    void bar(std::string str, int a, int b)
    {
    }
    
    template<typename T, typename ... Args>
    void foo(std::function<void(T, Args...)> fcn, Args ... args)
    {
        // Some code that calls fcn
    }
    
    
    int main() {
        std::function<void(std::string, int, int)> func_1 = bar;
        int a = 3;
        int b = 5;
        foo(func_1, a, b);
        return 0;
    }
    
    • If it is necessary to use Call by Reference, I tried it by giving a direct address and it worked in this case too.
    #include <iostream>
    #include <functional> 
    
    void bar(std::string str, int* a, int* b)
    {
    }
    
    template<typename T, typename ... Args>
    void foo(std::function<void(T, Args...)> fcn, Args ... args)
    {
        // Some code that calls fcn
    }
    
    
    int main() {
        std::function<void(std::string, int*, int*)> func_1 = bar;
        int a = 3;
        int b = 5;
        foo(func_1, &a, &b);
        return 0;
    }