C++ C++;函数对象模板参数推断样式

C++ C++;函数对象模板参数推断样式,c++,functional-programming,C++,Functional Programming,我正试图通过采用更具功能性的编程风格,将我的即席编程提炼成模块化和可重用的组件,但这让我不得不将所有东西都写两遍 例如,我有一个状态stateT state,它由一个可配置的函数对象step更新 template<typename sT, typename T1, typename T2> struct Step { T1 func1; T2 func2; Step(T1 f1, T2 f2) : func1(f1), func2(f2) {} sT operat

我正试图通过采用更具功能性的编程风格,将我的即席编程提炼成模块化和可重用的组件,但这让我不得不将所有东西都写两遍

例如,我有一个状态
stateT state
,它由一个可配置的函数对象
step
更新

template<typename sT, typename T1, typename T2>
struct Step {
  T1 func1;
  T2 func2;

  Step(T1 f1, T2 f2) : func1(f1), func2(f2) {}

  sT operator()(sT state) {
    state.A = func1(state.A);
    ... using func2() and internals of state ...
  }
};
现在我可以写作了

stateT state{...constructor arguments...};
auto step = make_stepper(state, func1, func2);
state = state(step);

为了提供一个好的界面,我最终为每个模板化函数对象
X
编写了一个
make_X
函数。这是好的风格还是我在自欺欺人?我可以避免编写
make_X
函数吗?或者我应该改变整个方法?

< P>这是通常的做法,也是C++标准库中的方法。因此,您的思路是正确的,无法避免编写make_uuu函数,因为无法按照要求直接对类/结构进行推导。

重新解释
auto
之后,事实上,事情已经变得比以前好得多了。请注意,您应该在
make_stepper
中使用完美转发来限制复制的数量。@MFH:我不同意,请参阅我的上一篇。@Mankka:因此,您不使用完美转发,而是使用显式转发来增加潜在的不必要/临时复制的数量,听起来很合理…@Mankka:这毕竟是你的选择,但如果你问使用
make_
-函数是否是一种好的风格,答案仍然是:是的,如果它们使用完美的转发(这就是标准如何定义
make_shared
make_unique
)。Kerrek SB甚至在你提到的问题中提到了这个解决方案。您似乎将算法(是的,通过值获取它们的函子)与工厂方法(通常不这样做,例如,
make_shared
)弄错了。它实际上非常简单:想要将参数传递给另一个函数(例如构造函数)?=>使用完美的转发!
template<typename sT, typename T1, typename T2>
auto make_stepper(sT state, T1 func1, T2 func2) {
  return Step<sT,T1,T2>(func1, func2);
}
stateT state{...constructor arguments...};
auto step = make_stepper(state, func1, func2);
state = state(step);