c++ - vectores - ¿Cómo pasar un VLA a una plantilla de función?
retornar un arreglo en c (6)
Tengo el siguiente código que no se pudo cumplir.
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;
}
}
¿Cuál es la forma correcta de pasar la matriz si la principal es algo como a continuación?
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);
}
error: no hay función de coincidencia para llamar a array_ini_1d ..............
A medida que utiliza la matriz de longitud variable (VLA) (extensión del compilador), el compilador no puede deducir N.
Tienes que pasarlo por el puntero y dar el tamaño:
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);
}
O use std::vector
. (sin extensión utilizada así). Lo cual parece más limpio:
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);
}
El problema es que las matrices de tamaño variable no son compatibles con c ++, y solo se admite como extensión de compiladores. Eso significa que el estándar no dice lo que debería suceder, y debería ver si puede encontrarlo en la documentación del compilador, pero dudo que dichos casos estén documentados.
Entonces, este es el problema:
int arr[n];
La solución es evitarlo, y usar algo soportado por c ++, como por ejemplo std::vector
.
No creo que el compilador pueda deducir el tamaño de una matriz de longitud variable en una plantilla. Además, no te olvides de enviar declarar f
antes de usarlo. Los arreglos de longitud variable son una extensión de GCC y debe recibir una advertencia con respecto a su uso.
Puedes declarar tu función así:
template <typename A, size_t N> void f(A a[N]) {
for(size_t i = 0; i < N; i++)
cout << a[i];
}
Sin embargo, el problema es que cuando llama a la función, el compilador no deducirá los parámetros de la plantilla, y tendrá que especificarlos explícitamente.
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;
}
Desafortunadamente, eso arruina la idea ...
UPD: E incluso ese código NO funciona para una matriz que tiene una longitud variable, ya que la longitud se calcula en tiempo de ejecución y los parámetros de la plantilla se definen en tiempo de compilación.
UPD2: si usa std::vector
, puede crearlo inicializado: vector<int> arr(n, 0);
O puede llenarlo con fill
de <algorithm>
cuando sea necesario: std::fill(arr.begin(), arr.end(), 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;
}
Los parámetros de la plantilla deben resolverse en tiempo de compilación.
No hay forma de que una plantilla de función con el parámetro size_t N
pueda coincidir con cualquier clase de matriz u otro contenedor cuyo tamaño provenga de una entrada en tiempo de ejecución.
Deberá proporcionar otra versión de la array_1d_ini
que no tenga el tamaño como parámetro de plantilla.