У меня есть некоторый вспомогательный код, который выполняет перестановку векторов, используя индексы времени компиляции. Крайне важно, чтобы сгенерированный код был максимально эффективным. Я полагаюсь на пакеты параметров с выражениями свертывания, и мне было интересно, как лучше всего писать такой код.
Практический пример: пусть существует функция insert
, которая вставляет элементы контейнера y
в контейнер x
в позициях Ii
, где позиции являются константами времени компиляции. Основная сигнатура этой функции будет выглядеть примерно так:
template<size_t... Ii, size_t Xsize, size_t Size>
constexpr container<Xsize> insert(container<Xsize> x, container<Ysize> y);
И это вызывается так: insert<0, 2>(x, y)
. Я вижу две очевидные возможности реализации этого.
Во-первых: использование вспомогательной индексной переменной для итерации по y
:
template<size_t... Ii, size_t Xsize, size_t Size>
constexpr container<Xsize> insert(container<Xsize> x, container<Ysize> y) {
int i = 0;
((x[Ii] = y[i++]), ...);
return x;
}
Моя проблема с этим решением - переменная i
: мне нужно полагаться на компилятор, чтобы оптимизировать его.
Второе решение позволяет избежать любых зависимостей во время выполнения, но требует вспомогательной функции, что делает всю реализацию довольно уродливой:
template<size_t... Ii, size_t... Yi, size_t Xsize, size_t Size>
constexpr container<Xsize> insert_(container<Xsize> x, container<Ysize> y, std::index_sequence<Yi...>) {
((x[Ii] = y[Yi]), ...);
return x;
}
template<size_t... Ii, size_t Xsize, size_t Size>
constexpr container<Xsize> insert(container<Xsize> x, container<Ysize> y) {
return insert_<Ii...>(x,y, std::make_index_sequence<sizeof...(Ii)> {});
}
Есть ли способ сделать это, избегая как переменных времени выполнения, так и вспомогательной функции?