Domanda

Sto cercando di scrivere una funzione di filtraggio generica che esegue l'interpolazione lineare in un dato campione di coordinate in un array multidimensionale (rango arbitrario). Per questo, ho bisogno di un modello di funzione ricorsiva che cammina attraverso tutte le dimensioni di un array fino a raggiungere un valore e il tipo associato. Io uso boost :: enable_if al fine di rilevare quando interrompere l'iterazione attraverso le dimensioni. E funziona bene fino a quando cerco di "percolato" il valore di ritorno / tipo alla funzione più in alto. A tal fine, ho cercato di utilizzare C ++ 0x inferenza di tipo, ma non sembra mescolare bene con boost :: enable_if.

I isolato il problema a quanto segue:

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

Il compilatore (GCC 4.6) si lamenta con il seguente codice:

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

Messaggio di errore:

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

Sembra che decltype utilizza il valore restituito da test anche se è raccomandato l'utilizzo di quella del test . Qualsiasi idea del perché si verifica questo comportamento? Per ora, è che mi limiterò a girare il tutto in un funtore ...

È stato utile?

Soluzione

Il problema è che avete passato una T () (e T) per decltype. I tipi non sono ribaltabili verso il basso. Questo si rivela chiaramente se si confronta l'espressione ritorno a ciò che è stato passato a decltype- Sono incoerenti.

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

Nel definire funzioni avanti come questo, il decltype espressione utilizzata per definire il tipo di ritorno dovrebbe essere quasi sempre esattamente lo stesso come l'espressione rendimento effettivo.

Modifica:. Ho bisogno di aggiungere che non si deve passare rvalues ??quando in realtà si passa lvalue, in particolare ai modelli, come si può ben finire con risultati diversi

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top