Supponiamo di avere una sequenza di tipi attraverso la quale voglio cercare:
template <typename...> struct TypeSequence { using type = TypeSequence; };
Voglio creare un metafunction Search
che restituisce true
se un determinato tipo esiste nella mia sequenza di tipo, o false
altrimenti, e Voglio che abbia di meglio di O (N ^ 2) spazio-complessità !
Al momento, in pratica, devo scorrere ogni elemento e creare un true_type
se il primo elemento corrisponde, oppure continuare con 1 dei tipi troncati finché non raggiungo la fine.
In C ++ assomiglia a questo:
template <typename Enable, typename Type, typename... T>
struct SearchImpl;
// empty type sequence
template <typename Type>
struct SearchImpl<void, Type> : std::false_type
{
};
// first element matches
template <typename Type, typename T1, typename... T>
struct SearchImpl<
typename std::enable_if<std::is_same<Type, T1>::value>::type,
Type, T1, T...>
:
std::true_type
{
};
// first element doesn't match
template <typename Type, typename T1, typename... T>
struct SearchImpl<
typename std::enable_if<!std::is_same<Type, T1>::value>::type,
Type, T1, T...>
:
SearchImpl<void, Type, T...>
{
};
// check if a type exists within a type list
template <typename TypeList, typename T>
struct Search;
template <template <typename...> class TypeList, typename T, typename... Types>
struct Search<TypeList<Types...>, T>
:
SearchImpl<void, T, Types...>
{
};
Per una sequenza di tipi di lunghezza N
con il tipo corrispondente situato a N/2
, questa operazione di ricerca crea N/2
tipi unici con una lunghezza dell'ordine N
ciascuno, equivalente a qualcosa nell'ordine di O ( N ^ 2) complessità dello spazio in fase di compilazione.
Esiste un modo per eseguire una ricerca di questo tipo con una complessità inferiore?
Quanto segue sarebbe molto economico, ma è illegale perché richiede un pacchetto variadico non alla fine dell'elenco degli argomenti:
template <typename T, typename... Types>
struct Has : std::false_type
{
};
template <typename T, typename... T1, typename... T2>
struct Has<T, T1..., T, T2...> : std::true_type // illegal!
{
};
Come posso inquadrare meglio una soluzione a questo problema per ridurre la complessità dello spazio (cioè il numero di tipi istanziati). So che posso ridurlo semplicemente cercando tra blocchi più grandi, ma questo non riduce la complessità stessa (cioè non scala bene).
La risposta può essere in pseudo-codice, purché scrivibile in codice template c ++.