Erro do GCC com modelos variadic: “Desculpe, não implementado: não é possível expandir 'Identificador…' em uma lista de argumentos de tamanho fixo”

Ao fazer a programação de modelos variadic em C ++ 11 no GCC, de vez em quando recebo um erro que diz "Desculpe, não implementado: não é possível expandir 'Identifier ...' em uma lista de arugamento de comprimento fixo." Se eu remover o "..." no código, obtenho um erro diferente: "error: packs de parâmetro não expandidos com '...'".

Então, se eu tiver o "...", o GCC chama isso de erro, e se eu tirar o "...", o GCC chama isso de erro também.

A única maneira que eu tenho sido capaz de lidar com isso é reescrever completamente o metaprograma de modelo a partir do zero usando uma abordagem diferente, e (com sorte) acabo criando código que não causa o erro. Mas eu realmente gostaria de saber o que estava fazendo de errado. Apesar de pesquisar no Google e apesar de muita experimentação, não consigo definir o que estou fazendo de forma diferente entre o código do modelo variadico que produz esse erro e o código que não possui o erro.

O texto da mensagem de erro parece implicar que o código deve funcionar de acordo com o padrão C ++ 11, mas que o GCC ainda não o suporta. Ou talvez seja um erro de compilador?

Aqui está um código que produz o erro. Nota: Eu não preciso que você escreva uma implementação correta para mim, mas apenas para apontar o que é sobre o meu código que está causando este erro específico

// 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;
};

EDITAR: Eu notei que, enquanto uma instanciação de modelo parcial parece incorrer no erro:

template <typename... T>
struct SomeStruct<1, 2, 3, T...> {};

Reescrevendo-o, pois isso não produz um erro:

template <typename... T>
struct SomeStruct<1, 2, 3, TypePack<T...>> {};

Parece que você podedeclarar Parâmetros para especializações parciais para ser variadic; ou seja, esta linha está OK:

template <typename... T>

Mas você não pode realmenteusar esses pacotes de parâmetros na especialização, ou seja, esta parte não está OK:

SomeStruct<1, 2, 3, T...>

O fato de você poder fazer isso funcionar se você encapsular o pacote em algum outro tipo, ou seja, assim:

SomeStruct<1, 2, 3, TypePack<T...>>

para mim implica que odeclaração O parâmetro variadic para uma especialização de modelo parcial foi bem-sucedido e você não pode usá-lo diretamente. alguém pode confirmar isso?

questionAnswers(4)

yourAnswerToTheQuestion