Tengo el siguiente código que no se pudo cumplir.
using namespace std; void f(int); template 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 abajo?
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 una función coincidente para llamar a array_ini_1d …………..
No creo que el comstackdor pueda deducir el tamaño de una matriz de longitud variable en una plantilla. Además, no olvide reenviar declarar f
antes de usarlo. Las matrices de longitud variable son una extensión GCC y debería recibir una advertencia sobre su uso.
El problema es que las matrices de tamaño variable no son compatibles con c ++, y solo se admite como extensión de comstackdores. 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 comstackdor, pero dudo que tales casos de esquina estén documentados.
Entonces, este es el problema:
int arr[n];
La solución es evitarlo y usar algo compatible con c ++, como por ejemplo std::vector
.
Puedes declarar tu función así:
template 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 comstackdor 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(arr); cout << endl; return 0; }
Desafortunadamente, eso arruina la idea misma ...
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 el momento de la comstackción.
UPD2: Si usa std::vector
puede crearlo inicializado: vector
O puede llenarlo con fill
desde
cuando sea necesario: std::fill(arr.begin(), arr.end(), 0);
A medida que usa la matriz de longitud variable (VLA) (extensión del comstackdor), el comstackdor no puede deducir N.
Tienes que pasarlo por puntero y dar el tamaño:
template 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 utilice std::vector
. (No se usa extensión así). Lo que parece más limpio:
template void array_ini_1d(std::vector& 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 arr(n); // or arr(n, 0). array_ini_1d(arr); }
Los parámetros de la plantilla deben resolverse en tiempo de comstackción.
No hay forma de que una plantilla de función con el parámetro size_t N
pueda coincidir con cualquier tipo de matriz u otro contenedor cuyo tamaño provenga de una entrada en tiempo de ejecución.
Deberá proporcionar otra versión del array_1d_ini
que no tenga el tamaño como parámetro de plantilla.
template void f(T* a) { /* add your code here */ } int main() { int a[10]; f(a); return 0; }