函数引用和指针

Function reference and pointer

我正在尝试使用编码良好的库为正态分布创建累积密度函数 (CDF)。该库的实施与我的问题无关。所以我这里只加了接口

void cumnor ( double *arg, double *result, double *ccum );

现在,我的成员函数接口:

double N(const double& x) const;

实施:

double EuropeanOption::N(const double& x) const
{ // cumulative density functions (CDF)
    
    double cum, ccum;
    cumnor(&x, &cum, &ccum);

    return cum; 
}

所以我的函数基本上采用 CDF 中积分 (x) 的上限和 return 值 P.

但编译器抛出以下内容:

EuropeanOption.cpp: In member function ‘double EuropeanOption::N(const double&) const’:
EuropeanOption.cpp:82:9: error: invalid conversion from ‘const double*’ to ‘double*’ [-fpermissive]
  cumnor(&x, &cum, &ccum);
         ^~
In file included from EuropeanOption.hpp:3:0,
                 from EuropeanOption.cpp:3:
cdflib.hpp:60:6: note:   initializing argument 1 of ‘void cumnor(double*, double*, double*)’
 void cumnor ( double *arg, double *result, double *ccum );
      ^~~~~~

我的问题是我应该如何编写此函数的代码?我只想称它为 N(d1)。我不太明白为什么我不能将 &x 作为第一个参数传递给这里。

I don't quite understand why i can't pass &x as first argument here.

&x 传递给需要 double* 作为参数类型的函数是不正确的。如果允许,它会让被调用的函数改变 x 的值,这是一个 const.

要解决此问题,请创建一个函数局部变量并使用它。

double EuropeanOption::N(const double& x) const
{ // cumulative density functions (CDF)
    
    double temp_x = x;
    double cum, ccum;
    cumnor(&temp_x, &cum, &ccum);

    return cum; 
}

作为一项额外的改进,在调用 cumnor.

之前将 cumccum 初始化为零
double EuropeanOption::N(const double& x) const
{ // cumulative density functions (CDF)
    
    double temp_x = x;
    double cum = 0, ccum = 0;
    cumnor(&temp_x, &cum, &ccum);

    return cum; 
}

您不能将 &x 传递给 cumnor(),因为 x 是对 const double 的引用,但 cumnor() 需要一个指向非const double 代替。非常量允许 cumnor() 允许 更改给定的 double 的值,如果需要的话。如果实际情况并非如此,那么它 应该 取一个指向 const double 的指针:

void cumnor ( const double *arg, double *result, double *ccum );

另一方面,确实没有充分的理由通过 const reference 传递 double。理想情况下,它应该 按值 传递,例如:

void cumnor ( double arg, double *result, double *ccum );
...
double EuropeanOption::N(double x) const
{ // cumulative density functions (CDF)
    
    double cum, ccum;
    cumnor(x, &cum, &ccum);

    return cum; 
}

但是,如果对 cumnor() 进行更改不是一个选项(即,因为您无权更改库的界面),那么您需要将 N() 更改为通过 cumnor() 想要的。例如,通过使用本地 double 变量,它是 x 指向的 doublecopy,例如:

double EuropeanOption::N(const double& x) const
{ // cumulative density functions (CDF)
    
    double x_copied = x, cum, ccum;
    cumnor(&x_copied, &cum, &ccum);

    return cum; 
}

或者,如果您确定 cumnor() 不会更改 double 的值,则可以改用 const_cast (不过,我相信人们会阻止你使用它),例如:

double EuropeanOption::N(const double& x) const
{ // cumulative density functions (CDF)
    
    double cum, ccum;
    cumnor(const_cast<double*>(&x), &cum, &ccum);

    return cum; 
}

或者,如果您只是通过值而不是指针获取 x,那么将 &x 传递给 cumnor() 就可以正常工作,同时保持 N() 的语义不能改变调用者的 double 变量,例如:

double EuropeanOption::N(double x) const
{ // cumulative density functions (CDF)
    
    double cum, ccum;
    cumnor(&x, &cum, &ccum);

    return cum; 
}