Błąd GCC z różnymi szablonami: „Przykro mi, niezaimplementowany: nie można rozwinąć„ Identyfikatora… ”na listę argumentów o stałej długości”
Wykonując zmienne programowanie szablonów w C ++ 11 w GCC, od czasu do czasu pojawia się błąd, który mówi: „Przepraszam, nie zaimplementowano: nie można rozwinąć„ Identyfikatora ... ”na listę arugmentów o stałej długości.” Jeśli usunę „...” w kodzie, to otrzymam inny błąd: „błąd: pakiety parametrów nie są rozszerzone o„ ... ”.
Więc jeśli mam „...” w GCC, wywołuje to błąd, a jeśli biorę „...”, GCC wywołuje to również błąd.
Jedynym sposobem, w jaki mogłem sobie z tym poradzić, jest całkowite przepisanie metaprogramu szablonu od podstaw przy użyciu innego podejścia i (przy odrobinie szczęścia) ostatecznie wymyślę kod, który nie powoduje błędu. Ale naprawdę chciałbym wiedzieć, co robię źle. Pomimo googlingu i pomimo wielu eksperymentów, nie mogę określić, co robię inaczej między kodem szablonu zmiennego, który powoduje ten błąd, a kodem, który nie ma błędu.
Brzmienie komunikatu o błędzie wydaje się sugerować, że kod powinien działać zgodnie ze standardem C ++ 11, ale GCC jeszcze go nie obsługuje. A może to błąd kompilatora?
Oto kod, który powoduje błąd. Uwaga: nie muszę pisać poprawnej implementacji dla mnie, ale po prostu wskazać, co jest związane z moim kodem, który powoduje ten konkretny błąd
// Used as a container for a set of types.
template <typename... Types> struct TypePack
{
// Given a TypePack<T1, T2, T3> and T=T4, returns TypePack<T1, T2, T3, T4>
template <typename T>
struct Add
{
typedef TypePack<Types..., T> type;
};
};
// Takes the set (First, Others...) and, while N > 0, adds (First) to TPack.
// TPack is a TypePack containing between 0 and N-1 types.
template <int N, typename TPack, typename First, typename... Others>
struct TypePackFirstN
{
// sorry, unimplemented: cannot expand ‘Others ...’ into a fixed-length argument list
typedef typename TypePackFirstN<N-1, typename TPack::template Add<First>::type, Others...>::type type;
};
// The stop condition for TypePackFirstN: when N is 0, return the TypePack that has been built up.
template <typename TPack, typename... Others>
struct TypePackFirstN<0, TPack, Others...> //sorry, unimplemented: cannot expand ‘Others ...’ into a fixed-length argument list
{
typedef TPack type;
};
EDYTOWAĆ: Zauważyłem, że podczas gdy częściowa instancja szablonu wygląda tak, powoduje błąd:
template <typename... T>
struct SomeStruct<1, 2, 3, T...> {};
Przepisywanie go, ponieważ nie powoduje to błędu:
template <typename... T>
struct SomeStruct<1, 2, 3, TypePack<T...>> {};
Wygląda na to, że możeszogłosić parametry do częściowych specjalizacji mają być zmienne; tj. ta linia jest OK:
template <typename... T>
Ale tak naprawdę nie możeszposługiwać się te pakiety parametrów w specjalizacji, tj. ta część nie jest w porządku:
SomeStruct<1, 2, 3, T...>
Fakt, że możesz to zrobić, jeśli opakujesz paczkę w inny typ, np. W ten sposób:
SomeStruct<1, 2, 3, TypePack<T...>>
dla mnie sugeruje, żedeklaracja parametru variadic do częściowej specjalizacji szablonu powiodło się i nie można go użyć bezpośrednio. Czy ktoś może to potwierdzić?