c++templatestemplate-argument-deduction

how missing template argument is valid in one but not valid in other function?


why template argument missing in print_all(arr&) is valid but not in f(std::vector&) ?

source code link.

What am I missing ? please explain what happens when we compile ?

template<typename T>
void print_all(T& rhs) 
{
    for(int i = 0; i < rhs.size(); i++) {
        std::cout << rhs[i] << " ";
    }

    std::cout << "\n";
}

void f(std::vector& v) 
{
    std::cout << v[0] << "\n";
}

int main() {
    arr<int, 4> a1 = {4, 5, 6, 7};

    arr<int, 4> a2 = std::move(a1);

    print_all(a2);

    std::vector<int, 4> v = {3, 5, 6, 7};
    f(v);;

}

Solution

  • In this call:

    print_all(a2);
    

    The type T of the template parameter rhs is deduced on the call site from the actual argument that you pass (a2). I.e. T is deduced to be arr<int, 4>.
    This C++ feature is called Template argument deduction.

    On the other hand, the case of your f is different.
    f It is not declared to be templated at all but a normal function.
    When the compiler compiles it it does not know what kind of std::vector v is supposed to be, and hence the errors.

    You can solve it by making f templated:

    template<typename T>
    void f(std::vector<T>& v) 
    {
        std::cout << v[0] << "\n";
    }
    

    Live demo

    Note:
    std::vector does not have a templated parameter for the size, which is dynamic. Therefore in this line:

    std::vector<int, 4> v = {3, 5, 6, 7};
    

    v should just be a std::vector<int>:

    std::vector<int> v = {3, 5, 6, 7};
    

    (this is already fixed in the live demo link above)