[英]Question on using class member function as template parameter
I'm reading the book by Daoqi Yang "C++ and Object Oriented Numeric Computing for Scientists and Engineers".我正在读杨道奇的书《C++ 和 Object 面向科学家和工程师的面向数值计算》。 He has a similar example to what I am showing below, but the exceptions are the class "P" I define and the second to last line (which doesn't work).
他有一个与我在下面展示的类似的示例,但例外情况是我定义的 class“P”和倒数第二行(不起作用)。 My question is: why does my compiler generate and error when I supply the function member f.integrand?
我的问题是:当我提供 function 成员 f.integrand 时,为什么我的编译器会生成错误? What can I do to correct this?
我该怎么做才能纠正这个问题? The errors being generated are C3867, C2440, and C2973.
生成的错误是 C3867、C2440 和 C2973。
Here is the code:这是代码:
class P{
public:
double integrand(double x){
return (exp(-x*x));
}
};
template<double F(double)>
double trapezoidal(double a, double b, int n)
{
double h=(b-a)/n;
double sum=F(a)*0.5;
for(int i=1;i<n;i++)
{
sum+=F(a+i*h);
}
sum+=F(b)*0.5;
return (sum*h);
}
double integrand2(double x){
return (exp(-x*x));
}
int main(){
P f;
cout<< trapezoidal<integrand2>(0,1,100)<<endl; // this works
cout<< trapezoidal<f.integrand>(0,1,100)<<endl; // this doesn't work
}
Template arguments must be compile-time constant expressions or types, and member functions require special handling anyway.模板 arguments 必须是编译时常量表达式或类型,成员函数无论如何都需要特殊处理。 Instead of doing this, use
boost::function<>
as an argument, and boost::bind
to create the functor, eg不要这样做,而是使用
boost::function<>
作为参数,并使用boost::bind
来创建仿函数,例如
double trapezoidal(double, double, boost::function<double(double)>);
// ...
P f;
trapezoidal(0, 1, 100, integrand2);
trapezoidal(0, 1, 100, boost::bind(&P::integrand, boost::ref(f)));
If you have 0x-capable compiler, you can use std::function
and std::bind
instead.如果您有支持 0x 的编译器,则可以改用
std::function
和std::bind
。
Cat Plus Plus is correct - boost::bind
is a good way to do this easily. Cat Plus Plus 是正确的 -
boost::bind
是轻松完成此操作的好方法。 I've also included an alternate solution with the following snippet of code:我还包含了一个带有以下代码片段的替代解决方案:
class P{
private:
double a;
public:
double integrand(double x){
return (a*exp(-x*x));
}
void setA(double y){
a = y;
}
void getA(){
cout<<a<<endl;
}
struct integrand_caller {
P* p;
integrand_caller(P& aP) : p(&aP) {};
double operator()(double x) const {
return p->integrand(x);
};
};
};
template <typename Evaluator, typename VectorType>
VectorType trapezoidal(Evaluator f, const VectorType& a, const VectorType& b, int n)
{
VectorType h=(b-a)/n;
VectorType sum=f(a)*0.5;
for(int i=1;i<n;i++)
{
sum+=f(a+i*h);
}
sum += f(b)*0.5;
return (sum*h);
}
double integrand2(double x){
return (exp(-x*x));
}
int main(){
P f[5];
for(int i=0;i<5;i++){
f[i].setA(5*i);
f[i].getA();
cout<< trapezoidal(P::integrand_caller(f[i]),(double)0, (double)1, 100) << endl;
cout<<trapezoidal(boost::bind(&P::integrand,f[i],_1), 0.0, 1.0, 100)<<"\n"<<endl;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.