При выполнении вариационного программирования шаблонов в С++ 11 в GCC время от времени появляется сообщение об ошибке "Извините, не реализовано: невозможно развернуть" Идентификатор... "в список исправлений фиксированной длины". Если я удалю "..." в коде, тогда получаю другую ошибку: "error: пакеты параметров не расширены с помощью "..." .
Итак, если у меня есть "..." , GCC вызывает эту ошибку, и если я возьму "..." , GCC вызовет также и ошибку.
Единственный способ, с которым я смог справиться, - полностью переписать метапрограмму шаблона с нуля с использованием другого подхода, и (с удачей) я в конечном итоге придумал код, который не вызывает ошибку. Но я действительно хотел бы знать, что я делаю неправильно. Несмотря на то, что для него и для Google, и несмотря на много экспериментов, я не могу определить, что я делаю по-разному между вариационным кодом шаблона, который вызывает эту ошибку, и кодом, который не имеет ошибки.
Формулировка сообщения об ошибке означает, что код должен работать в соответствии со стандартом С++ 11, но GCC еще не поддерживает его. Или, возможно, это ошибка компилятора?
Вот код, который вызывает ошибку. Примечание. Мне не нужно писать для меня правильную реализацию, а просто указать, что такое мой код, вызывающий эту конкретную ошибку.
// 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;
};
РЕДАКТИРОВАТЬ: Я заметил, что, хотя похожее на экземпляр частичного экземпляра вызывает ошибку:
template <typename... T>
struct SomeStruct<1, 2, 3, T...> {};
Переписывание, поскольку это не вызывает ошибки:
template <typename... T>
struct SomeStruct<1, 2, 3, TypePack<T...>> {};
Кажется, что вы можете объявлять параметры для частичных специализаций вариационными; то есть эта строка в порядке:
template <typename... T>
Но вы не можете использовать эти пакеты параметров в специализации, то есть эта часть не подходит:
SomeStruct<1, 2, 3, T...>
Тот факт, что вы можете заставить его работать, если вы завернете пакет в какой-то другой тип, например:
SomeStruct<1, 2, 3, TypePack<T...>>
для меня подразумевается, что объявление вариационного параметра для специализации частичного шаблона было успешным, и вы просто не можете использовать его напрямую. Кто-нибудь может это подтвердить?