C ++ 0x líos tipo de inferencia con impulso :: enable_if
-
15-10-2019 - |
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
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