Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
std::tr1::函数和std::tr1::bind 我在C++类中使用了非常复杂的C函数(重写C函数不是一个选项)。C功能: typedef void (*integrand) (unsigned ndim, const double* x, void* fdata, unsigned fdim, double* fval); // This one: int adapt_integrate(unsigned fdim, integrand f, void* fdata, unsigned dim, const double* xmin, const double* xmax, unsigned maxEval, double reqAbsError, double reqRelError, double* val, double* err);_C++_C++11_Tr1 - Fatal编程技术网

std::tr1::函数和std::tr1::bind 我在C++类中使用了非常复杂的C函数(重写C函数不是一个选项)。C功能: typedef void (*integrand) (unsigned ndim, const double* x, void* fdata, unsigned fdim, double* fval); // This one: int adapt_integrate(unsigned fdim, integrand f, void* fdata, unsigned dim, const double* xmin, const double* xmax, unsigned maxEval, double reqAbsError, double reqRelError, double* val, double* err);

std::tr1::函数和std::tr1::bind 我在C++类中使用了非常复杂的C函数(重写C函数不是一个选项)。C功能: typedef void (*integrand) (unsigned ndim, const double* x, void* fdata, unsigned fdim, double* fval); // This one: int adapt_integrate(unsigned fdim, integrand f, void* fdata, unsigned dim, const double* xmin, const double* xmax, unsigned maxEval, double reqAbsError, double reqRelError, double* val, double* err);,c++,c++11,tr1,C++,C++11,Tr1,我需要自己提供一个被积函数类型的空函数,adapt_integral将计算n维积分。如果func是独立函数,则calcTripleIntegral(以下)中的代码作为独立函数工作。 我想传递一个(非静态的!)类成员函数作为被积函数,因为这很容易重载等等 class myIntegrator { public: double calcTripleIntegral( double x, double Q2, std::tr1::function<integrand> &f

我需要自己提供一个
被积函数类型的空函数,adapt_integral将计算n维积分。如果
func
是独立函数,则
calcTripleIntegral
(以下)中的代码作为独立函数工作。 我想传递一个(非静态的!)类成员函数作为被积函数,因为这很容易重载等等

class myIntegrator
{
public:
    double calcTripleIntegral( double x, double Q2, std::tr1::function<integrand> &func ) const
    {
        //...declare val, err, xMin, xMax and input(x,Q2) ...//
        adapt_integrate( 1, func, input,
                         3, xMin, xMax,
                         0, 0, 1e-4,
                         &val, &err);
        return val;
    }
    double integrandF2( unsigned ndim, const double *x, void *, // no matter what's inside
                 unsigned fdim, double *fval) const;            // this qualifies as an integrand if it were not a class member
    double getValue( double x, double Q2 ) const
    {
        std::tr1::function<integrand> func(std::tr1::bind(&myIntegrator::integrandF2, *this);
        return calcTripleIntegral(x,Q2,func);
    }
}
类myIntegrator
{
公众:
双calcTripleIntegral(双x,双Q2,标准::tr1::函数和函数)常数
{
//…声明val、err、xMin、xMax和输入(x,Q2)//
自适应_积分(1,函数,输入,
3,xMin,xMax,
0,0,1e-4,
&val和err);
返回val;
}
double integrandF2(无符号ndim,常数double*x,void*,//无论内部是什么
无符号fdim,double*fval)const;//如果它不是类成员,则符合被积函数的条件
双getValue(双x,双Q2)常量
{
std::tr1::function func(std::tr1::bind(&myIntegrator::integrandF2,*this);
返回calcTripleIntegral(x,Q2,func);
}
}
在GCC 4.4.5(预发行版)中,这给了我:

错误:变量“std::tr1::function func”具有初始值设定项,但类型不完整

编辑:我的代码中有什么错误?我现在尝试使用GCC 4.4、4.5和4.6进行编译,所有这些都导致了相同的错误。要么没有对此做任何工作,要么我做错了什么/EDIT

非常感谢!如果我不够清楚,我很乐意详细说明

PS:我可以在没有tr1的情况下,通过使用指向myIntegrator.cpp中某个地方定义的函数的函数指针来解决这个问题吗

<强>最后更新< /强>:好吧,我错误地认为Tr1提供了一个/两个线的解决方案。BuMME。我正在“转换”我的类到命名空间和复制函数声明。我只需要一个基类和一个子类重新实现接口。C函数指针+ C++类=坏消息对我来说。 感谢所有的答案,你给我展示了一些C++的暗角;

< P>我想把一个(非静态的)类成员函数传递成整合式…< /P> 你不能。如果您搜索使用成员函数作为回调函数,您一定会找到有用的信息,包括您正在尝试做的事情,不管怎样,直接方法是不可能的

编辑:顺便说一句,代码中的一个问题(当然还有更多的问题,因为您试图做的是根本不可能的)是您向函数传递了一个函数指针类型,而它期望的是一个签名。函数模板的实现方式如下:

template < typename Signature >
struct function;

// for each possible number of arguments:
template < typename R, typename Arg1, typename Arg2 >
struct function<R(Arg1,Arg2)>
{
   ... body ...
};
模板
结构功能;
//对于每个可能的参数数:
模板
结构函数
{
…身体。。。
};
正如您所看到的,传递一个函数指针到这类事情是编译器无法理解的。它将尝试实例化forward声明,但却一无所获。这当然是你得到的编译器错误意味着什么,但它并没有解决你的根本问题,那就是你所做的永远不会起作用


在一个完全C++0x编译器中,这可以以不同的方式完成,但是boost::function和MSVC必须是这样的。此外,C++0x版本将遇到与您当前面临的问题相同的问题。

该错误消息听起来好像您缺少所涉及类型之一的包含。至少尝试再次检查您的
被积函数
tr1
包含?

绑定
的工作原理与您认为的有点不同。您需要为每个参数提供一个值或占位符

对于您的示例,这归结为(带占位符)

std::tr1::function func(std::tr1::bind(&myIntegrator::integrandF2,*this,_1,_2,_3,_4,_5));
由于绑定的是一个成员函数,因此有一个额外的(隐式)参数,即调用成员函数的对象,因此有六个

对于第一个绑定
this
对象,对于其他参数,只需传递占位符

另一方面,您的成员函数返回double,而函数声明返回void


(作为记录,我仍在使用一个较旧的编译器,几乎不支持tr1,因此我只有
bind
function
使用boost的经验,tr1可能会有一些变化…

您有三个问题。。。首先,您需要一个
std::tr1::function
,但您的可以归结为
std::tr1::function
——因此您需要两个typedef:

typedef void (integrand) (unsigned ndim, const double *x, void *,
                       unsigned fdim, double *fval);
typedef integrand* integrand_ptr;
。。。因此,第一个允许您使用可编译的
函数
<代码>自适应\u集成
必须相应地固定:

int adapt_integrate(unsigned fdim, integrand_ptr f, ...);
接下来,您的
bind
语法处于禁用状态,它应该是:

std::tr1::bind(&myIntegrator::integrandF2, *this, _1, _2, _3, _4, _5);
剩下的问题是
tr1::function
不能转换为函数指针,因此您必须遍历包装函数,使用
void*fdata
参数传递上下文。例如,类似于:

extern "C" void integrand_helper (unsigned ndim, const double *x, void* data,
                                  unsigned fdim, double *fval)
{
    typedef std::tr1::function<integrand> Functor;
    Functor& f = *static_cast<Functor*>(data);
    f(ndim, x, data, fdim, fval);
}

// ...
adapt_integrate(1, &integrand_helper, &func, ...);

由于std::tr1::bind和c风格的函数指针不协调,请尝试使用此方法。它将工作,除了
myIntegrator::getValue
不再是线程安全的。如果从接口中删除
calcTripleIntegral
,这将更加简单,不需要使用
std::tr1::bind
std::tr1::function

class myIntegrator
{
public:
   double getValue( double x, double Q2 ) const
   {
       return calcTripleIntegral(x,Q2,std::tr1::bind(&Integrator::integrandF2,this));
   }

   double calcTripleIntegral( double x, double Q2, const std::tr1::function<integrand>& func ) const
   {
      assert( s_integrator == NULL );
      s_integrator = this;
      m_integrand = func;

      //...declare val, err, xMin, xMax and input(x,Q2) ...//
      adapt_integrate( 1, &myIntegrator::fancy_integrand, input,
                       3, xMin, xMax,
                       0, 0, 1e-4,
                       &val, &err);

      assert( s_integrator == this);
      s_integrator = NULL;

      return val;
   }
private:
   double integrandF2( unsigned ndim, const double *x, void *,
                unsigned fdim, double *fval) const;

   static double fancy_integrand( unsigned ndim, const double* x, void* input,
                                  unsigned fdim, double* fval)
   {
      s_integrator->integrateF2(ndim,x,input,fdim,fval);
   }

   std::tr1::function<integrand> m_integrand;
   static const myIntegrator* s_integrator;
};
class myIntegrator
{
public:
   // getValue is no longer const.  but integrandF2 wasn't changed
   double getValue( double x, double Q2 )
   {
      m_x = x;
      m_Q2 = Q2;

      // these could be members if they need to change
      const double xMin[3] = {0.0};
      const double xMax[3] = {1.0,1.0,1.0};
      const unsigned maxEval = 0;
      double reqAbsError = 0.0;
      double reqRelError = 1e-4;

      double val;

      adapt_integrate( 1, &myIntegrator::fancy_integrand,
                       reinterpret_cast<void*>(this),
                       3, xMin, xMax,
                       maxEval, reqAbsError, reqRelError,
                       &val, &m_err);

      return val;
   }

   double get_error()
   { return m_error; }

private:
   // use m_x and m_Q2 internally
   // I removed the unused void* parameter
   double integrandF2( unsigned ndim, const double *x,
                       unsigned fdim, double *fval) const;

   static double fancy_integrand( unsigned ndim, const double* x, void* this_ptr,
                                  unsigned fdim, double* fval)
   {
      myIntegrator& self = reinterpret_cast<myIntegrator*>(this_ptr);
      self.integrateF2(ndim,x,fdim,fval);
   }

   double m_x
   double m_Q2;
   double m_err;
};
类myIntegrator
{
公众:
双getValue(双x,双Q2)常量
{
返回calcTripleIntegral(x,Q2,std::tr1::bind(&Integrator::integrandF2,this));
}
双计算积分(双x,双Q2,con
class myIntegrator
{
public:
   double getValue( double x, double Q2 ) const
   {
       return calcTripleIntegral(x,Q2,std::tr1::bind(&Integrator::integrandF2,this));
   }

   double calcTripleIntegral( double x, double Q2, const std::tr1::function<integrand>& func ) const
   {
      assert( s_integrator == NULL );
      s_integrator = this;
      m_integrand = func;

      //...declare val, err, xMin, xMax and input(x,Q2) ...//
      adapt_integrate( 1, &myIntegrator::fancy_integrand, input,
                       3, xMin, xMax,
                       0, 0, 1e-4,
                       &val, &err);

      assert( s_integrator == this);
      s_integrator = NULL;

      return val;
   }
private:
   double integrandF2( unsigned ndim, const double *x, void *,
                unsigned fdim, double *fval) const;

   static double fancy_integrand( unsigned ndim, const double* x, void* input,
                                  unsigned fdim, double* fval)
   {
      s_integrator->integrateF2(ndim,x,input,fdim,fval);
   }

   std::tr1::function<integrand> m_integrand;
   static const myIntegrator* s_integrator;
};
#include <iostream>
#include <tr1/functional>

typedef void (*callback_function_t)(void *input, int arg);

struct data_type { 
  int x;
};

struct context_type {
  std::tr1::function<void(data_type const &, int)> func;
  data_type data;
};

void callback(data_type const&data, int x) {
  std::cout << data.x << ", " << x << std::endl;
}

void callback_relay(void *context, int x) {
  context_type const *ctxt = reinterpret_cast<context_type const*>(context);
  ctxt->func(ctxt->data, x);
}

void call_callback(callback_function_t func, void *context, int x) {
  func(context, x);
}

int main() {
  context_type ctxt = { callback, { 1 } };

  call_callback(callback_relay, &ctxt, 2);
}
class myIntegrator
{
public:
   // getValue is no longer const.  but integrandF2 wasn't changed
   double getValue( double x, double Q2 )
   {
      m_x = x;
      m_Q2 = Q2;

      // these could be members if they need to change
      const double xMin[3] = {0.0};
      const double xMax[3] = {1.0,1.0,1.0};
      const unsigned maxEval = 0;
      double reqAbsError = 0.0;
      double reqRelError = 1e-4;

      double val;

      adapt_integrate( 1, &myIntegrator::fancy_integrand,
                       reinterpret_cast<void*>(this),
                       3, xMin, xMax,
                       maxEval, reqAbsError, reqRelError,
                       &val, &m_err);

      return val;
   }

   double get_error()
   { return m_error; }

private:
   // use m_x and m_Q2 internally
   // I removed the unused void* parameter
   double integrandF2( unsigned ndim, const double *x,
                       unsigned fdim, double *fval) const;

   static double fancy_integrand( unsigned ndim, const double* x, void* this_ptr,
                                  unsigned fdim, double* fval)
   {
      myIntegrator& self = reinterpret_cast<myIntegrator*>(this_ptr);
      self.integrateF2(ndim,x,fdim,fval);
   }

   double m_x
   double m_Q2;
   double m_err;
};