Как передать VLA в шаблон функции?

У меня есть следующий код, который не может быть соблюден.

using namespace std;
void f(int);
template<typename T1, size_t N>
void array_ini_1d(T1 (&x)[N])
{
for (int i = 0; i < N; i++)
{
x[i] = 0;
}
}

Как правильно передать массив, если main что-то вроде ниже?

int main()
{
int a;
cin >> a;
int n = a / 4;
f(n);
return 0;
}

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

ошибка: нет подходящей функции для вызова array_ini_1d …………..

1

Решение

Я не думаю, что компилятор может определить размер массива переменной длины в шаблоне. Кроме того, не забудьте переслать объявить f прежде чем использовать его. Массивы переменной длины являются расширением GCC, и вы должны получить предупреждение об их использовании.

1

Другие решения

Проблема в том, что массивы переменного размера не поддерживаются c ++ и поддерживаются только как расширение компиляторов. Это означает, что стандарт не говорит о том, что должно произойти, и вы должны посмотреть, сможете ли вы найти его в документации компилятора, но я сомневаюсь, что такие угловые случаи документированы.

Итак, это проблема:

int arr[n];

Решение состоит в том, чтобы избежать этого и использовать что-то, поддерживаемое c ++, как, например, std::vector,

2

Вы можете объявить свою функцию следующим образом:

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

Однако проблема в том, что при вызове функции компилятор не будет выводить параметры шаблона, и вам придется указывать их явно.

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

К сожалению, это разрушает саму идею …

UPD: И даже этот код НЕ работает для массива с переменной длиной, так как длина вычисляется во время выполнения, а параметры шаблона определяются во время компиляции.

UPD2: При использовании std::vector Вы можете создать его инициализированным:
vector<int> arr(n, 0);
Или вы можете заполнить его fill от <algorithm> при необходимости:
std::fill(arr.begin(), arr.end(), 0);

1

Поскольку вы используете массив переменной длины (VLA) (расширение компилятора), компилятор не может вывести N.

Вы должны передать его указателем и указать размер:

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

Или использовать std::vector, (расширение не используется так). Который кажется чище:

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

Параметры шаблона должны быть разрешены во время компиляции.

Нет способа, чтобы шаблон функции с параметром size_t N может соответствовать любому виду массива или другого контейнера, размер которого поступает из входных данных во время выполнения.

Вам нужно будет предоставить другую версию array_1d_ini который не имеет размер в качестве параметра шаблона.

0
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;
}
-1
По вопросам рекламы [email protected]