2009-11-17 11 views
8

tengo tiene el siguiente código usando plantillas y dimensión de matriz como parámetro de plantilla no tipoC++ parámetro de plantilla en dimensión de matriz

template<int n> double f(double c[n]); 
... 
double c[5]; 
f<5>(c); // compiles 
f(c); // does not compile 

no debería el compilador para poder instanciar el segundo f sin parámetro de plantilla explícito? Estoy usando g ++ 4.1

+0

MSVC le permitirá salirse con la suya. –

+0

VC8 no lo hará, al menos no con una configuración sana :) –

+0

Estaba equivocado. MSVC te permite doblar (c) [n], lo cual obviamente no es lo mismo. Comeau también es genial con doble (& c) [n]. Increíble la diferencia que harán algunos paréntesis. –

Respuesta

28

Funciona al utilizar referencias:

template<size_t n> double f(double (&c)[n]); 
+0

gracias esto es exactamente lo que he estado necesitando – Anycorn

1

Desafortunadamente no, porque cuando pasa double c[5] a f(), o cualquier matriz a cualquier función que toma una matriz para ese asunto, pierde la información de tamaño. Solo está pasando un puntero.

Editar: Pero vea la respuesta de gf para una solución.

+2

Su comentario, aunque es correcto, no está relacionado. Es cierto que, en tiempo de ejecución, no hay forma de determinar el tamaño de una matriz, pero la deducción de parámetros de la plantilla ocurre en tiempo de compilación. El compilador sabe que el tamaño de la matriz es 5 y puede deducir el parámetro de la plantilla en consecuencia, aunque existen algunas limitaciones al respecto. – boycy

+0

No hay forma en el tiempo de ejecución para determinar el tipo declarado original de primitiva * any *. Perderá información cuando la pase a una función que espera un puntero, pero la pierde de la misma forma que pierde información cuando pasa un flotante a una función que espera un entero. Para ser más específico, el tipo de matriz en el momento de la declaración es "matriz de 5 dobles" o doble [5]. El tipo de matriz de tamaño tiene un molde implícito en un puntero. Este elenco es tan común que tendemos a olvidar que no es el tipo original de la matriz, pero es un tipo tan válido como cualquier otro. –

0

no, porque en una llamada diferente, el argumento podría provenir de cualquier parte. el compilador seguramente no puede perseguir sus punteros en el tiempo de ejecución.

edit: por cierto, esto funciona para mí, pero requiere -std = C++ 0x (estoy usando gcc 4,4)

#include <iostream> 

template <int n> 
struct T 
{ 
    T& 
    operator=(double const cc[n]) 
    { 
     c = cc; 
     return *this; 
    } 
    const double 
    operator[](int const &i) 
    { 
     return c[i]; 
    } 
    double c[n]; 
}; 

template<int n> 
double 
f(T<n> & x) 
{ 
    return x[n-1]; 
} 

int 
main() 
{ 
    T<5> t5 = {10, 20, 30, 40, 50}; 
    T<3> t3 = {100, 200, 300}; 
    std::cout << f(t5) << std::endl; 
    std::cout << f(t3) << std::endl; 
    return 0; 
} 
-1

Esto podría ayudarte con tu problema mayor (cualquiera que sea). Esto le permitirá consultar el tamaño/tipo de la matriz en la compilación.

template < typename T_, unsigned N_ > 
class many { 
public: 
    typedef T_ T; 
    enum { N = N_ }; 

    T array[N]; 
}; 

Justin

+0

¿Eh? ¿Cómo ayuda esto? – bobbogo

Cuestiones relacionadas