У меня есть следующий код, который не может быть соблюден.
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 …………..
Я не думаю, что компилятор может определить размер массива переменной длины в шаблоне. Кроме того, не забудьте переслать объявить f
прежде чем использовать его. Массивы переменной длины являются расширением GCC, и вы должны получить предупреждение об их использовании.
Проблема в том, что массивы переменного размера не поддерживаются c ++ и поддерживаются только как расширение компиляторов. Это означает, что стандарт не говорит о том, что должно произойти, и вы должны посмотреть, сможете ли вы найти его в документации компилятора, но я сомневаюсь, что такие угловые случаи документированы.
Итак, это проблема:
int arr[n];
Решение состоит в том, чтобы избежать этого и использовать что-то, поддерживаемое c ++, как, например, std::vector
,
Вы можете объявить свою функцию следующим образом:
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);
Поскольку вы используете массив переменной длины (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);
}
Параметры шаблона должны быть разрешены во время компиляции.
Нет способа, чтобы шаблон функции с параметром size_t N
может соответствовать любому виду массива или другого контейнера, размер которого поступает из входных данных во время выполнения.
Вам нужно будет предоставить другую версию array_1d_ini
который не имеет размер в качестве параметра шаблона.
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;
}