Реализация на C++14 make_integer_sequence
Я попытался реализовать с++14 make_integer_sequence шаблон псевдоним, которое упрощает создание шаблона класса [
integer_sequence`]2.
template< class T, T... I> struct integer_sequence
{
typedef T value_type;
static constexpr size_t size() noexcept { return sizeof...(I) ; }
};
template< class T, T N>
using make_integer_sequence = integer_sequence< T, 0,1,2, ... ,N-1 >; // only for illustration.
Для реализации make_integer_sequence
нам нужен помощник структуру make_helper
.
template< class T , class N >
using make_integer_sequence = typename make_helper<T,N>::type;
Реализации make_helper
это'т слишком сложно.
template< class T, T N, T... I >
struct make_helper
{
typedef typename mpl::if_< T(0) == N,
mpl::identity< integer_sequence<T,I...> >,
make_helper< T, N-1, N-1,I...>
>::type;
};
Для теста make_integer_sequence
я сделал это главным образом функция:
int main()
{
#define GEN(z,n,temp) \
typedef make_integer_sequence< int, n > BOOST_PP_CAT(int_seq,n) ;
BOOST_PP_REPEAT(256, GEN, ~);
}
Я скомпилировал программу с помощью GCC 4.8.0, на четырехъядерной системе i5 с 8GBs оперативной памяти. Успешная компиляция заняла 4 секунды.
Но, когда я сменила ген макрос:
int main() {
#define GEN(z,n,temp) \
typedef make_integer_sequence< int, n * 4 > BOOST_PP_CAT(int_seq, n) ;
BOOST_PP_REPEAT(256, GEN, ~ );
}
Компиляция была неудачной и выдается сообщение об ошибке:
виртуальная память исчерпана.
Может кто-нибудь объяснить эту ошибку и чем она вызвана?
Редактировать:
Я упрощенный тест:
int main()
{
typedef make_integer_sequence< int, 4096 > int_seq4096;
}
Затем я скомпилировал с 4.8.0 -ftemplate-глубина ССЗ=65536.
Однако этот второй тест:
int main()
{
typedef make_integer_sequence< int, 16384 > int_seq16384;
}
Не удалось скомпилировать с 4.8.0 -ftemplate-глубина ССЗ=65536, и вылилось в ошибки:
виртуальная память исчерпана.
Итак, мой вопрос, Как уменьшить глубокие шаблона, инстанцирования?
С уважением, Хуршид.
Здесь'ы реализация
отчет N
что не'т даже увеличенная максимальная глубина для шаблона, инстанцирования и составляет довольно быстро:Это в основном меня взлом вокруг Хео'ы решение: создание сообщества Вики - если ценит, пожалуйста, голосуйте Хео.
...просто изменен, пока я не чувствовал, что это не'т получить любой проще, переименовал и добавил, что
с value_type
иразмер () в стандарт (но только делаешь
index_sequenceне
integer_sequence), и код работает с GCC 5.2
-с std=с++14` может работать, в противном случае без изменений под старые/другие компиляторы я'м застрял с. Может спасти кого-то какое-то время / путаница.Примечания:
в "Магия" из приемо-передатчика'ный раствор в декларации
_merge_and_renumber
(функция concat
в его код) с точностью до двух параметров, а specilisation эффективно подвергает их отдельных параметров пакетовв
имя_типа
...`::тип в...структура make_index_sequence : _merge_and_renumber<make_index_sequence&ЛТ имя_типа;Н/2>::тип, make_index_sequence&ЛТ имя_типа;Н - П/2>::тип>
&ампер;усилитель; nbsp;&ампер;усилитель; nbsp;&ампер;усилитель; nbsp;&ампер;усилитель; nbsp;во избежание ошибок:
Я нашел очень быстро и излишне глубокая рекурсия варианте осуществления
make_index_sequence
. В моем компьютере он компилирует с N = 1 048 576 , с 2 сек. (ПК : ОС CentOS 6.4 с архитектурой x86, i5 процессор, 8 Гб ОЗУ, на GCC-4.4.7 -с std=с++0х -О2 -стена).Вам не хватает
-1
здесь:в частности:
Далее, первое отделение должно'т быть
integer_sequence в<Т>
, аinteger_sequence<Т, Я...>
.которых должно быть достаточно, чтобы получить исходный код для компиляции.
В общем, при написании серьезных "шаблон" метапрограммирование, ваша главная цель должна держать глубину "шаблон" инстанцирование вниз. Способ думать об этой проблеме не мерещится, у вас есть бесконечное-нить компьютер: каждый независимый расчет должен быть заковыляла на своем собственном потоке, затем перемешиваются вместе в конце. У вас есть несколько операций, что займет O(1) глубина, как
...
расширение: использовать.Обычно, вытягивать логарифмической глубины достаточно, потому что с
900
глубина, что позволяет2^900
большие структуры, и еще что-то сломается первым. (Чтобы быть справедливым, что это более вероятно, произойдет на 90 разных слоев2^10
размер структуры).Вот еще немного более общий вариация Хео's в логарифмических ответ, который обеспечивает make_integer_sequence для произвольных типов. Это делается с помощью функции std::integral_constant, чтобы избежать страшной "и шаблон аргумент шаблон включает параметр" и ошибка.
Демо: coliru
Простая реализация за o(n) времени. Наверное, не то, что вы хотите для больших n, но мое приложение является только для вызова функций с проиндексированных Аргументы, и я бы'т ожидать арности больше, чем примерно 10. Я не'т заполнить в члены integer_sequence. Я'м глядя вперед, чтобы с помощью реализации стандартной библиотеки и уничтожить этого :)