admin管理员组

文章数量:1289911

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

}

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

}
Share Improve this question edited Feb 21 at 15:34 Jesper Juhl 31.5k3 gold badges53 silver badges76 bronze badges asked Feb 21 at 7:58 Jitu DeRapsJitu DeRaps 1461 silver badge10 bronze badges 2
  • 1 You have typos: void f(std::vector& v) -> void f(std::vector<int>& v) and std::vector<int, 4> -> std::vector<int> – JeJo Commented Feb 21 at 8:02
  • 1 When you call print_all the type T is deduced from a2. In f the template arg for std::vector is missing and f is not templated at all. Type deduction only works on the call site if the function is declared as templated. – wohlstad Commented Feb 21 at 8:02
Add a comment  | 

2 Answers 2

Reset to default 4

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)

Because you don't understand the difference between a function and a function template. In your code print_all() is a function template that takes type T. It's only instantiated if the compiler detects a call to print_all(T), and your print_all() code assumes that T has defined operator[]. f is a function (not a function template), which is always instantiated, that takes type std::vector, which is ill-formed, as all vectors require a type they hold, i.e. std::vector<int>, std::vector<char*>, std::vector<something_i_found_under_thecouch>, there is no such thing as just std::vector. If you want your print_all() function to work with any vector, you'll need to redeclare it as a function template:

template <class T>
void f(const std::vector<T>& v);

and/or

template <class T>
void f(std::vector<T>&& v);

Cheers!

本文标签: chow missing template argument is valid in one but not valid in other functionStack Overflow