La spécialisation est la condition de terminaison. Notez qu'il exige que First
égal Search
:
type_index<Index, Search, Search, Types ...>
^^^^^^ ^^^^^^
Par exemple, si vous commencez avec
type_index<0, C, A, B, C, D>,
cela ne se conforme pas à la spécialisation, de sorte que le modèle générique sera utilisé, la redirection (via son type
membre) à
type_index<0, C, A, B, C, D>::type = type_index<1, C, B, C, D>::type
mais ce n'est pas évaluables, soit jusqu'à ce que la chaîne atteigne
type_index<0, C, A, B, C, D>::type = ... = type_index<2, C, C, D>::type
A ce stade, la spécialisation partielle peut être utilisé, qui dit que
type_index<2, C, C, D>::type = type_index<2, C, C, D>
type_index<2, C, C, D>::index = 2
et ainsi
type_index<0, C, A, B, C, D>::type::index = 2
^^^^
0 1 2 3
comme prévu.
Notez que vous n'avez pas besoin de porter le Index
autour et peut en effet laisser tomber toute chose ::type
:
template<typename, typename...>
struct type_index;
template<typename Search, typename Head, typename... Tail>
struct type_index<Search, Head, Tail...> {
// Search ≠ Head: try with others, adding 1 to the result
static constexpr size_t index = 1 + type_index<Search, Tail...>::index;
};
template<typename Search, typename... Others>
struct type_index<Search, Search, Others...> {
// Search = Head: if we're called directly, the index is 0,
// otherwise the 1 + 1 + ... will do the trick
static constexpr size_t index = 0;
};
template<typename Search>
struct type_index<Search> {
// Not found: let the compiler conveniently say "there's no index".
};
Cela fonctionne comme:
type_index<C, A, B, C, D>::index
= 1 + type_index<C, B, C, D>::index
= 1 + 1 + type_index<C, C, D>::index
= 1 + 1 + 0
= 2
et si le type n'est pas parmi la liste, dira quelque chose comme (GCC 6.2.1):
In instantiation of ‘constexpr const size_t type_index<X, C>::index’:
recursively required from ‘constexpr const size_t type_index<X, B, C>::index’
required from ‘constexpr const size_t type_index<X, A, B, C>::index’
required from [somewhere]
error: ‘index’ is not a member of ‘type_index<X>’
que je trouve assez explicite.
Je pense que l'auteur (s) respectif (s) aurait dû aller avec le 'TODO' en premier lieu ... ;-) –
cela produira un message d'erreur * lovely * si le type' Search' n'est pas parmi ceux cherché ... – Walter