Question

Je suis en train d'écrire une fonction de filtrage générique qui effectue une interpolation linéaire sur une coordonnée échantillonnage donnée dans un tableau multidimensionnel (rang arbitraire). Pour cela, je besoin d'un modèle de fonction récursive qui marche dans toutes les dimensions d'un tableau jusqu'à ce qu'il atteigne une valeur et son type associé. J'utilise boost :: enable_if afin de détecter quand arrêter itérer à travers les dimensions. Il fonctionne bien jusqu'à ce que j'essaie de « lixiviat » la valeur de retour / type à la fonction supérieure. A cet effet, je tenté d'utiliser l'inférence de type C ++ 0x, mais il ne semble pas bien mélanger avec boost :: enable_if.

J'isolé le bas problème à ce qui suit:

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]);
}

Le compilateur (GCC 4.6) se plaint avec le code suivant:

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

Message d'erreur:

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

Il semble que decltype utilise la valeur de retour de test même si il est demandé d'utiliser celle de l'essai . Toute idée pourquoi ce problème se produit? Pour l'instant, il pense que je vais tourner la chose dans un foncteur ...

Était-ce utile?

La solution

Le problème est que vous avez passé un T () (et T) à decltype. Les types ne sont pas rabattant. Ceci est clairement révélé si l'on compare l'expression de retour à ce que vous avez passé à leur decltype- incompatibles êtes la.

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

Lors de la définition des fonctions avant comme celui-ci, l'decltype expression utilisée pour définir le type de retour doit presque toujours être exactement la même chose que l'expression de rendement réel.

Edit:. Je dois ajouter que vous ne devriez pas passer rvalues ??quand, en réalité, vous passerez lvalues, en particulier aux modèles, comme vous pouvez retrouver avec des résultats différents

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top