Variadic шаблоны, извинения компилятора - PullRequest
4 голосов
/ 11 октября 2011

Я уже задавал подобный вопрос раньше, понял, что могу заставить его работать частично за счет специализации. Но чтобы понять основы шаблонов, я изменил код следующим образом.

template<typename T, typename... args>
struct counter{
static const int value= 1+ counter<args...>::value;
};

template<typename T>
struct counter<T>{
static const int value = 0;
};

ошибка : «извините, не реализовано: невозможно развернуть« args ... »в список аргументов фиксированной длины»

Я понимаю, что это ошибка, и она была исправлена ​​в gcc 4.7.0

так что, чтобы исправить все это, мы должны использовать трюк или что-то еще, что частично специализирует шаблон.

template<typename... Args> struct counter;

template<>
struct counter<> {
static const int value = 0;
};

template<typename T, typename... Args>
struct counter<T, Args...> {
static const int value = 1 + counter<Args...>::value;
};

Актуальный вопрос : поэтому я действительно хочу знать, какой особый эффект дает частичная специализация, чтобы код работал, или я должен спросить, как частичная специализация решает проблему? (почему вторая версия не попадает в ошибку?). Любое объяснение с проблемой мотивации и примерами будет очень полезно.

Ответы [ 2 ]

3 голосов
/ 13 октября 2011

Вторая версия позволяет избежать ошибки, поскольку основной шаблон объявлен как template<typename...>, то есть он вариативный.Ключ к ошибке в сообщении об ошибке: «извините, не реализовано: невозможно развернуть« args ... »в список аргументов фиксированной длины » (выделено мной).

Таким образомcounter<Args...>::value будет работать во втором случае, потому что counter приспособлен для приема любого количества аргументов.Однако в первом случае, когда первичный шаблон объявлен как template<typename T, typename... args>, компилятор должен разделить args на фиксированную длину часть (T) и переменную часть (новый *)1015 *).Предположительно, это та самая функциональность, которая не реализована в вашей версии GCC.

У меня нет оснований полагать, что какой-либо механизм позволяет специализации <T, Args...> второго случая соответствовать первичному шаблону <typename...>повторно используется для расширения фиксированной длины.

(Наконец, поскольку поддержка функций C ++ 11 помечена GCC как «экспериментальная», вы действительно не можете ожидать, что будет работать, а что нет.гораздо меньше почему и как . На подобные вопросы могут только разумно ответить разработчики GCC в своем списке рассылки, а не мы. Мы не против читателей.)

0 голосов
/ 11 октября 2011

Специальный код - первый случай.Это происходит, чтобы поразить определенную ошибку компилятора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...