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ć?

questionAnswers(4)

yourAnswerToTheQuestion