Подтвердить что ты не робот

Масштабируемость вариационных шаблонов

Я работаю над крупномасштабной программной инфраструктурой в С++ 11, которая широко использует вариационные шаблоны. Мой вопрос заключается в следующем: какова масштабируемость этого подхода? Во-первых, существует ли верхний предел числа аргументов, которые могут принимать вариативные шаблоны? Во-вторых, код раздувает серьезную проблему с самыми современными компиляторами, когда используется много аргументов (и, по большому счету, многие комбинации этих аргументов, которые могут привести к множеству различных реализаций шаблонных методов)?

4b9b3361

Ответ 1

Я подумал, что мне нужно выяснить, существует ли ограничение на количество параметров шаблона для моего конкретного компилятора (g++ 4.8.1 в Linux). Я использовал следующий тестовый пример:

template <int I>
struct this_is_a_ridiculously_long_struct_name_youd_never_use_in_real_life {};

template <int Depth, typename... T>
struct A
{
    using e = this_is_a_ridiculously_long_struct_name_youd_never_use_in_real_life<Depth>;

    A() {};

    A<Depth - 1, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, T...> a;
};

template <typename... T>
struct A<0, T...>
{
};

int main()
{
    A<899> a;
}

Предел глубины рекурсии шаблона по умолчанию равен 900 в g++, поэтому параметр 899 вы видите. Нелепо длинное имя структуры используется, чтобы увидеть, могу ли я генерировать любые символы, которые были слишком большими для компоновщика для обработки - больше об этом за секунду.

Если вы не видите, что происходит в тестовом примере, в основном каждое создание A создает переменную-член, которая добавляет 20 дополнительных параметров шаблона. Частичная специализация используется для остановки рекурсии. К концу, A<0, ...> имеет где-то в области 18000 параметров шаблона.

Я обнаружил, что g++ справился с этим просто отлично. Понадобилось довольно много времени, чтобы подумать об этом, и использовал справедливый бит памяти, но мне не удалось заставить его потерпеть неудачу, просто увеличив количество параметров шаблона. Clang 3.1 также справлялся с этим без каких-либо проблем после того, как глубина рекурсии шаблона была установлена ​​достаточно (то есть 900).

Кроме того, хотя искомые имена символов действительно становятся огромными, я не смог сломать их nm или ld, используя их. (Стоит отметить, что схема манипулирования Linux/Itanium использует подстановку, так что повторяющиеся параметры шаблона того же типа не повторяют целое имя типа, а скорее обозначаются S0, S1 и т.д.). Быстрый google doesn ' t, похоже, ограничивает длину символа ELF, но, возможно, кто-то еще знает, существует ли такой предел.

В заключение, для g++ и clang по Linux, по крайней мере, , похоже, нет никакого практического ограничения на количество параметров шаблона.

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