C ++函数模板,函数作为参数,依赖于其他参数

时间:2016-02-25 21:03:28

标签: c++ templates

我有线搜索算法的实现,例如this Brent method,我想制作一个通用模板,它允许我针对一个参数x优化任何标量函数,但我想插入error_func,这不仅仅依赖于xtypedef double( *scalar_function1D )(double); // this function vary "x" in order to make error_func(x) close to zero template< scalar_function1D error_func> double lineSearch_Brent ( double x, double xmin, double xmax, double tol ){ double f = error_func(x); while( abs( f )>tol ){ f = error_func(x); // body of line search algorithm, details not important } return x; } 上,还有一些其他参数。

也许(伪)代码更能说明我想要做的事情:

一般图书馆:

// we would like to find optimal "x" for this model_error function for given "params"
double model_error( double x, int n, double * params ... /* many other parameters there */ ){
    // body of specific model for error function which depends on "x" but also on other parameters; details not importaint
}

double optimize_x_for_given_model( double xmin, double ymin, int n, double * params ){
   // how to plug in "params" now ?!?
   return lineSearch_Brent<model_error>( 0.5*(xmin+xmax), xmin, xmax, 1.0e-8 );
} 

特定用例:

model_error
明显的问题scalar_function1D不属于class Scalar_function1D{ public virtual double eval(double); } // shared interface class Model_error : public Scalar_function1D { // specific implementation public: int n; double * params; virtual double eval(double){ // body which depends on "params" }; } 类型,因为它有更多参数。

我知道这种问题可以通过面向对象编程来解决,例如像这样:

ID     Column1    
101     a    
101     b     
101     c    
102     aa   
102     bb   
102     cc    
103     b   
103     a      
103     c  
104     cc  
104     aa 
104     bb   
105     c  
105     a 
105     b

但我想知道如何使用功能模板。

1 个答案:

答案 0 :(得分:2)

而不是传递非类型模板参数:

template< scalar_function1D error_func>
double lineSearch_Brent ( double x, double xmin, double xmax, double tol ) { ... }

只传递一个任意函数对象:

template <class ScalarFunction1D>
double lineSearch_Brent (ScalarFunction1D error_func, double x, 
    double xmin, double xmax, double tol ) { ... }

这允许你只传入一个捕获其他一些参数的lambda:

lineSearch_Brent([=](double x){ return model_error(x, n, params); },
     0.5*(xmin+xmax), xmin, xmax, 1.0e-8);

或任何适当的。