Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-template type arguments

Tags:

c++

templates

I have this template function:

template<int i> void f(int a[i]) { };

int main () {
   int c[10];
   f(c); // Causes an error!
}

Why cant i pass c[10] as a non-template type argument to a template function?

like image 592
Vis Viva Avatar asked Dec 01 '22 02:12

Vis Viva


2 Answers

Remember that a function parameter that looks like an array is actually a pointer, so your template is actually equivalent to

template<int i> void f(int * a);

with no way to deduce the template argument from the function argument. You could specify it explicitly:

f<10>(c);

but that's rather error prone; a better option is to pass the array by reference, so that the template argument can be deduced:

template<int i> void f(int (&a)[i]);

Alternatively, in C++11 or later, you could use std::array which is a sensible object type with none of the quirks of built-in array types.

like image 149
Mike Seymour Avatar answered Dec 04 '22 12:12

Mike Seymour


Actually the correct function template would use std::size_t as template argument:

template<std::size_t i> void f(int (&a)[i])

But using an std::array is probably better:

template<std::size_t i> void f(const std::array<int, i>&)

You should also consider using iterators, if the algorithm you are developing in f is supposed to work with any container that provide iterators:

template<class It> void f(It begin, It end)

so that you can use your function like this:

int x[10]                = ...;
std::vector<int> y       = ...;
std::array<int, 10> z    = ...;

f(std::begin(x), std::end(x));
f(std::begin(y), std::end(y));
f(std::begin(z), std::end(z));

The latter is often used by the STL library for their container-independent algorithms.

like image 43
Shoe Avatar answered Dec 04 '22 13:12

Shoe