Pregunta

Estoy intentando escribir una función de filtrado genérica que realiza la interpolación lineal en una muestra dada coordinan en una matriz multidimensional (rango arbitrario). Para esto, necesito una plantilla de función recursiva que camina a través de todas las dimensiones de un array hasta que llega a un valor y su tipo asociado. Yo uso impulso :: enable_if con el fin de detectar cuándo dejar de iterar a través de las dimensiones. Funciona bien hasta que intento "percolado" el valor de retorno / tipo a la función superior. Con este fin, he tratado de utilizar C ++ 0x inferencia de tipos, pero no parece que se mezcla bien con el impulso :: enable_if.

Me aisló el problema hacia abajo a lo siguiente:

template< typename T, std::size_t I >
auto test(const T &t) -> typename boost::enable_if_c< (I == 0), typename T::value_type >::type
{
    return t[0];
}

template< typename T, std::size_t I >
auto test(const T &t) -> typename boost::enable_if_c< (I > 0), decltype(test< T, I - 1 >(T())) >::type
{
    return test< typename T::value_type, std::size_t(I - 1) >(t[0]);
}

El compilador (GCC 4.6) se queja con el código siguiente:

typedef std::array< std::array< float, 1 >, 1 > myarray;
myarray ma;
std::cout << typeid (test< myarray, 1 >(ma)).name() << std::endl;

Mensaje de error:

error: conversion from 'boost::enable_if_c<true, float>::type' to non-scalar type 'boost::enable_if_c<true, std::array<float, 1u> >::type' requested

Parece que decltype utiliza el valor de retorno de prueba a pesar de que se le instruye para que el uso de la prueba . Cualquier idea de por qué se produce este comportamiento? Por ahora, creo que voy a su vez todo el asunto en un funtor ...

¿Fue útil?

Solución

El problema es que se aprobó una T () (y T) a decltype. Los tipos no son plegables hacia abajo. Esto se revela claramente si se compara la expresión de retorno a lo que pasó a decltype- Son inconsistentes.

template< typename T, std::size_t I >
auto test(const T &t) -> typename boost::enable_if_c< (I > 0), decltype(test< T, I - 1 >(T())) >::type
{
    return test< typename T::value_type, std::size_t(I - 1) >(t[0]);
}

decltype: test<T

return expression: test< typename T::value_type

Cuando se definen las funciones de avance de este tipo, el decltype expresión utilizada para definir el tipo de retorno debe casi siempre ser exactamente el mismo que el rendimiento real de expresión.

Editar:. Tengo que añadir que no se debe pasar rvalues ??cuando en realidad se pasa a lvalues, especialmente a las plantillas, como bien puede terminar con resultados diferentes

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