How to pass a VLA to a function template?

戏子无情 提交于 2019-11-28 14:24:02

I don't think the compiler can deduce the size of a variable-length array in a template. Also, don't forget to forward declare f before you use it. Variable-length arrays are a GCC extension and you should get a warning regarding their use.

The problem is that variable size arrays are not supported by c++, and is only supported as compilers extension. That means, the standard doesn't say what should happen, and you should see if you can find in compiler's documentation, but I doubt that such corner cases are documented.

So, this is the problem :

int arr[n];

The solution is to avoid it, and use something supported by c++, like for example std::vector.

You may declare your function like this:

template <typename A, size_t N> void f(A a[N]) {
    for(size_t i = 0; i < N; i++)
        cout << a[i];
}

However, the problem is that when you call the function, the compiler won't deduce the template parameters, and you will have to specify them explicitly.

char arr[5] = {'H', 'e', 'l', 'l', 'o'};

int main()
{
    //f(arr); //Won't work
    f<char, sizeof(arr)/sizeof(arr[0])>(arr);
    cout << endl;
    return 0;
}

Unfortunately, that ruins the very idea...

UPD: And even that code does NOT work for an array that has variable length, for the length is calculated at runtime, and the template parameters are defined at compilation time.

UPD2: If using std::vector you may create it initialized: vector<int> arr(n, 0); Or you may fill it with fill from <algorithm> when needed: std::fill(arr.begin(), arr.end(), 0);

As you use Variable length array (VLA) (compiler extension), compiler cannot deduce N.

You have to pass it by pointer and give the size:

template<typename T>
void array_ini_1d(T* a, std::size_t n)
{
    for (std::size_t i = 0; i != n; ++i) {
        a[i] = 0;
    }
}

void f(int n)
{
    int arr[n];
    array_ini_1d(arr);
}

Or use std::vector. (no extension used so). Which seems cleaner:

template<typename T>
void array_ini_1d(std::vector<T>& v)
{
    for (std::size_t i = 0, size = v.size(); i != n; ++i) {
        a[i] = 0; // or other stuff.
    }
}

void f(int n)
{
    std::vector<int> arr(n); // or arr(n, 0).
    array_ini_1d(arr);
}

Template parameters must be resolved at compile-time.

There is no way that a function template with parameter size_t N can match any sort of array or other container whose size comes from a run-time input.

You will need to provide another version of the array_1d_ini which does not have the size as a template parameter.

template<typename T, size_t N>
void f(T* a)
{
/* add your code here */
}

int main()
{
    int a[10];
    f<int, 10>(a);
    return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!