C/C 11 中的函数组合

新手上路,请多包涵

我目前正在用 C++11 编写一些需要大量函数组合的加密算法。我必须处理两种类型的组合:

  1. 在其自身上组合一个函数的次数不定。在数学上,对于某个函数 F,F^n(x) = (F^{n-1} o F)(x) = F^{n-1}(F(x))。

  2. 将不同的功能组合在一起。例如,对于某些相同类型的函数 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);

我想自己编写这个函数 n 次。我以一种简单的递归方式实现了组合,效果很好:

 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 是可变的?我认为可变参数模板在这里会很有用,但我不知道在这种情况下如何使用它们。

谢谢你的帮助。

原文由 Gabriel L. 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 450
2 个回答

这些方面的东西,也许(未经测试):

 template <typename F>
class Composer {
  int n_;
  F f_;
public:
  Composer(int n, F f) : n_(n), f_(f) {}

  template <typename T>
  T operator()(T x) const {
    int n = n_;
    while (n--) {
      x = f_(x);
    }
    return x;
  }
};

template <int N, typename F>
Composer<F> compose(F f) {
  return Composer<F>(N, f);
}

编辑: 对于第二种情况( 这次测试):

 #include <iostream>

template <typename F0, typename... F>
class Composer2 {
    F0 f0_;
    Composer2<F...> tail_;
public:
    Composer2(F0 f0, F... f) : f0_(f0), tail_(f...) {}

    template <typename T>
    T operator() (const T& x) const {
        return f0_(tail_(x));
    }
};

template <typename F>
class Composer2<F> {
    F f_;
public:
    Composer2(F f) : f_(f) {}

    template <typename T>
    T operator() (const T& x) const {
        return f_(x);
    }
};

template <typename... F>
Composer2<F...> compose2(F... f) {
    return Composer2<F...>(f...);
}

int f(int x) { return x + 1; }
int g(int x) { return x * 2; }
int h(int x) { return x - 1; }

int main() {
  std::cout << compose2(f, g, h)(42);
  return 0;
}

原文由 Igor Tandetnik 发布,翻译遵循 CC BY-SA 3.0 许可协议

带有参数转发的函数迭代的快速实现。不幸的是,辅助类型是必需的,因为函数模板不能部分专门化。

 #include <functional>
#include <iostream>
using namespace std;

template<int n, typename A>
struct iterate_helper {
  function<A(A)> f;
  iterate_helper(function<A(A)> f) : f(f) {}
  A operator()(A&& x) {
    return f(iterate_helper<n - 1, A>(f)(forward<A>(x)));
  };
};

template<typename A>
struct iterate_helper<1, A> {
  function<A(A)> f;
  iterate_helper(function<A(A)> f) : f(f) {}
  A operator()(A&& x) {
    return f(forward<A>(x));
  };
};

template<int n, typename A>
function<A(A)> iterate(function<A(A)> f) {
  return iterate_helper<n, A>(f);
}

int succ(int x) {
  return x + 1;
}

int main() {
  auto add5 = iterate<5>(function<int(int)>(succ));
  cout << add5(10) << '\n';
}

原文由 Jon Purdy 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏