Pregunta

template <typename T> void function(T arg1, 
    T min = std::numeric_limits<T>::min(),
    T max = std::numeric_limits<T>::max())
{
}

template <> void function<int>(int arg1, int min,int max)
{
}

int main(int argc,char* argv[])
{
    function<int>(1);
}

muestra el error de sintaxis C2689 y C2059 en la línea de argumento predeterminada de la función en :: simbólico.pero sin especialización, le va bien.Y si cambio el argumento predeterminado y sigo haciendo especialización:

template <typename T> void function(T arg1, 
    T min = T(0),
    T max = T(1))
{
}
template <> void function<int>(int arg1, int min,int max)
{
}

el problema también desapareció.

ahora si lo uso así: function<int>(1,2,3); o function<float>(1.0f) está bien, entonces parece que si la función de plantilla está especializada, debemos reescribir el argumento predeterminado cuando la llamamos.

pero en mi segundo caso, donde reemplazo std::numeric_limits<T>::.. con T(..) no hay error de sintaxis al llamar function<int>(1), ¿porqué es eso?

(Estoy usando Visual Studio 2010 x64)

Como el problema original se debe a un error, la pregunta ahora cambió a ¿Cómo solucionarlo?

¿Fue útil?

Solución

No hay nada malo con el código;Comeau Online, Intel C++ 11.1 y g++ 4.1.2 lo compilan correctamente.

Supongo que es un error en el compilador.Recientemente envié un artículo relacionado, pero ligeramente diferente. informe de error contra el compilador de Visual C++ 2010.


Como solución alternativa, puede ajustar las llamadas:

template <typename T>
T get_limits_min() { return std::numeric_limits<T>::min(); }

template <typename T>
T get_limits_max() { return std::numeric_limits<T>::max(); }

template <typename T> void function(T arg1, 
    T min = get_limits_min<T>(),
    T max = get_limits_max<T>())
{
}

¿Feo?Bastante.


Publiqué lo siguiente en respuesta a el error que informó en Microsoft Connect:

La plantilla principal debe tener un parámetro que tenga un valor de argumento predeterminado.El valor del argumento predeterminado debe ser una función miembro de una plantilla de clase que no esté en el espacio de nombres global.

El siguiente es el código mínimo para reproducir:

namespace N
{
    template <typename T>
    struct S
    {
        static T g() { return T(); }
    };
}

template <typename T> void f(T = N::S<T>::g()) { }

template <> void f<>(int) { }

int main()
{
    f<int>();
}

El compilador emite los siguientes errores, ambos en la línea donde está definida la plantilla principal:

error C2589: '::' : illegal token on right side of '::'
error C2059: syntax error : '::'

Curiosamente, existe otro problema si la plantilla de clase está en el espacio de nombres global.Dado el siguiente código:

template <typename T>
struct S
{
    static T g() { return T(); }
};

template <typename T> void f(T = ::S<T>::g()) { }

template <> void f<>(int) { }

int main()
{
    f<int>();
}

El compilador emite el siguiente error en la línea en la que se define la plantilla principal:

error C2064: term does not evaluate to a function taking 0 arguments

Ambos casos de prueba de ejemplo son programas C++ bien formados.

Otros consejos

Como respuesta aquí en https://stackoverflow.com/a/13566433/364084 y https://stackoverflow.com/a/27443191/364084 , esto es debido a min y max macro se define en la cabecera de ventanas. El siguiente código debería funcionar mediante la prevención de la expansión de la macro:

template <typename T> void function(T arg1, 
    T min = (std::numeric_limits<T>::min)(),
    T max = (std::numeric_limits<T>::max)())
{
}

template <> void function<int>(int arg1, int min,int max)
{
}

int main(int argc,char* argv[])
{
    function<int>(1);
}

Se recopiló succeesfully ... en     Comeau línea, http:. //Codepad.org,EDG compilador, y G ++

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top