В настоящее время я кодирую некоторые криптографические алгоритмы в C++ 11, для которых требуется множество композиций функций. Есть два типа состава, которые мне приходится иметь дело:Состав функции в C++/C++ 11
Составить функцию на себе переменное количество раз. Математически для некоторой функции F, F^n (x) = (F^{n-1} o F) (x) = F^{n-1} (F (x)).
Составить различные функции вместе. Например, для некоторых функций f, g, h, i, j и k того же типа у меня будет f (g (h (i (j (k (x)))))).
В моем случае, я использую следующее определение F:
const std::vector<uint8_t> F(const std::vector<uint8_t> &x);
Я хотел бы сочинить эту функцию на себя п раз. Я выполнил композицию в простой рекурсивной способом, который работает отлично:
const std::vector<uint8_t> compose(const uint8_t n, const std::vector<uint8_t> &x)
{
if(n > 1)
return compose(n-1, F(x));
return F(x);
}
В этом случае, есть более эффективный способ надлежащим образом реализовать эту композицию с помощью C++ 11, но без использования BOOST ? Было бы здорово, чтобы использовать эту форму, если это возможно, конечно:
answer = compose<4>(F)(x); // Same as 'answer = F^4(x) = F(F(F(F(x))))'
Во втором случае, я хотел бы реализовать состав с переменным числом функций. Для заданного набора функций F0, F1, ..., Fn, имеющих такое же определение, что и F, существует эффективный и правильный способ их компоновки, где n является переменной? Я думаю, что здесь будет полезен вариационный шаблон, но я не знаю, как их использовать в этом случае.
Благодарим за помощь.
Если вы используете STL, вы можете использовать 'unary_compose' (и заглянуть в его реализацию). – BatchyX
Возможно, что ваш компилятор уже [оптимизирует хвостовую рекурсию] (http://stackoverflow.com/q/34125/420683). – dyp
* Боковое примечание *: Подпись 'F' требует создания нового вектора (который может быть удален только в том случае, если компилятор встроен в' F'). Обычно не рекомендуется возвращать объект 'const', потому что он запрещает семантику перемещения. С сигнатурой, подобной 'std :: vector F (std :: vector )' (sic, pass-by-value), вы могли бы использовать перемещение elision и, возможно, работать с одним и тем же вектором со всеми 'F' s, сохраняя «непреложная» семантика. –
dyp