Fill<T, Pack, Size, Value>
deve essere il tipo Pack<Value, Value, ..., Value>
, dove viene ripetuto il valore. Qualcuno può spiegare, perché questo è ambiguo?Qualcuno spiega perché l'ambiguità qui, per favore?
template <typename T, template <T...> class Pack, int Size, int Count, typename Output, T Value>
struct FillHelper;
template <typename T, template <T...> class P, int Size, int Count, T... Output, T Value>
struct FillHelper<T, P, Size, Count, P<Output...>, Value> :
FillHelper<T, P, Size, Count + 1, P<Output..., Value>, Value> {};
template <typename T, template <T...> class P, int Size, T... Output, T Value>
struct FillHelper<T, P, Size, Size, P<Output...>, Value> {
using type = P<Output...>;
};
template <typename T, template <T...> class P, int Size, T Value>
using Fill = typename FillHelper<T, P, Size, 0, P<>, Value>::type;
template <int...> struct Pack;
int main() {
using T = Fill<int, Pack, 10, 4>;
}
mentre questo non è:
template <typename T, int Size, int Count, typename Output, T Value>
struct FillHelper;
template <typename T, template <T...> class P, int Size, int Count, T... Output, T Value>
struct FillHelper<T, Size, Count, P<Output...>, Value> :
FillHelper<T, Size, Count + 1, P<Output..., Value>, Value> {};
template <typename T, template <T...> class P, int Size, T... Output, T Value>
struct FillHelper<T, Size, Size, P<Output...>, Value> {
using type = P<Output...>;
};
template <typename T, template <T...> class P, int Size, T Value>
using Fill = typename FillHelper<T, Size, 0, P<>, Value>::type;
template <int...> struct Pack;
int main() {
using T = Fill<int, Pack, 10, 4>;
}
Si scopre che ho indirettamente notato che il secondo è più breve e quindi migliore del primo, ma ero perplesso perché il primo non sarebbe la compilazione. Ottengo un errore con GCC 4.9.2, che è molto recente. Errore anche con Visual Studio 2013. A proposito, una soluzione migliore del secondo codice è benvenuta.
Aggiornamento: Ridurre ulteriormente il problema, si scopre che la presenza del modello-modello nelle specializzazioni non è il problema, perché questo non compilare con GCC 4.9.2 (e Visual Studio 2013 troppo):
template <typename T, template <T...> class Pack, int Size, int Count>
struct F;
template <typename T, template <T...> class P, int Size, int Count>
struct F : F<T, P, Size, Count + 1> {};
template <typename T, template <T...> class P, int Size>
struct F<T, P, Size, Size> {
using type = int;
};
template <int...> struct Pack;
int main() {
using T = F<int, Pack, 10, 0>::type;
}
Quindi, qual è esattamente il problema nel primo codice che causa confusione con GCC e VS?
FWIW, clang 3.6 munches giù il primo senza errori. Info: Apple LLVM versione 6.1.0 (clang-602.0.49) (basato su LLVM 3.6.0svn). Forse includi le tue informazioni su toolchain. – WhozCraig
Ottengo un errore con GCC 4.9.2, che è molto recente. Errore anche con Visual Studio 2013. – prestokeys
Beh, il clang è apparentemente più intelligente di quello che siamo, in quanto realizza che di questo non è in realtà * usato *. Aggiungere 'T t;' a 'main()' fornisce una dose di: main.cpp: 23: 7: Istanza implicita del template non definito 'Pack <4, 4, 4, 4, 4, 4, 4 , 4> '. Anche se potrebbe essere utile saperlo a prescindere. ** modifica ** nm. aggiungendo '{};' dopo 'Pack' e compila ancora una volta. – WhozCraig