c++ - 我可以将成员函数传递给 mu::Parser::DefineFun() 吗?

标签 c++ boost c++98 muparser

我正在使用muParser解析数学表达式,我想向解析器添加一个函数,其实现将由类的非静态成员函数提供。此摘录自an example program应该告诉我我想做什么:

struct MyClass { // some boilerplate omitted
    double make_a_value(double a,  double b); // implemented elsewhere
};

int main(const int argc, const char** argv) {
    MyClass instance;
    mu::Parser p;
    p.DefineFun("f", MORE_MAGIC(MyClass::make_a_value, &instance));
    p.SetExpr("f(3, 2)");
    std::cout << p.Eval() << std::endl;
}

其中 MORE_MAGIC(...) 代表具有签名 double f(double arg1, double arg2) 的内容,相当于调用 instance-> make_a_value(arg1,arg2)。我不知道 MORE_MAGIC 应该是什么才能使其发挥作用。这就是我问题的本质。

DefineFun 的第二个参数可以具有以下任意函数签名:

  • 双 f()
  • 双 f(双)
  • 双 f(双, 双)
  • 依此类推,最多 10 个参数
  • double f(double*, int) 其中第一个指针是数组,int 是其长度
  • double f(const char*)
  • double f(const char*, double)
  • double f(const char*, double)

不幸的是,这些都不包含我可以用来传递实例的 void* 数据参数。我想到要颠覆一个 double* 来传递实例,但问题实际上是 muParser 根本不允许我预先定义要传递给函数的值;仅传递从解析表达式中获取的参数。

通过阅读其他几篇文章( 12345 ),我似乎需要的是一个绑定(bind)函数,以及执行此操作的首选方法(在 C 中)++98) 是 boost::bind。但我尝试将 MORE_MAGIC(...) 替换为 boost::bind(&wrapper, _1, _2, &instance),以及

double wrapper(double a, double b, MyClass* p) {
    return p->make_a_value(a, b);
}

(希望语法正确)并且我收到编译器错误:

/usr/include/muParserBase.h:134:95: error: no matching function for call to ‘mu::ParserCallback::ParserCallback(boost::_bi::bind_t<double, double (*)(double, double, MyClass*), boost::_bi::list3<boost::arg<1>, boost::arg<2>, boost::_bi::value<MyClass*> > >&, bool&)’
       AddCallback( a_strName, ParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );

等等。恶心。

我猜问题是 boost::bind 返回一个 boost::function,而我需要一个标准函数,并且根据 this answer如果没有一些 void* 来存储实例指针,从 boost::function 获取标准函数或多或少是不可能的。但我不确定我的理解是否正确,因为对 Boost 的经验很少,所以我的初步问题是:任何人都可以确认 boost::bind 只是不会我需要它做什么?

我的主要问题是:是否有任何方法可以实现这一目标?即使它涉及 C++ 魔法的神秘 secret ? (或者*喘息*切换到C++11?)

最佳答案

遗憾的是,muParser API 似乎还没有为 C++ 做好准备。

在 C++11 中,Lambda 可以“衰减”为函数指针,但这意味着它们必须是无状态的,因此,您又回到了同样的情况:无法绑定(bind)额外的参数。

muParser 是开源的吗?也许有一个 fork 已经修正了这个设计缺陷


哦,是的,boost::bind 不能打破物理定律 为你做到这一点

关于c++ - 我可以将成员函数传递给 mu::Parser::DefineFun() 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27088272/

相关文章:

c++ - 错误 C2100 - 非法间接

c++ - 我的应用程序中的内存增加

c++ - 将构造函数参数转发给放置新运算符

c++ - boost 线程对象生命周期和线程生命周期

c++ - 避免使用模板分配抽象类型

c++ - 这段代码可以在我的 PC 上编译,但不能在竞赛服务器上的标准 C++98 编译器上编译

c++ - 将 float 转换为 double 并返回 float 在 C++ 中给出相同的值吗

C++ 如何在 vector 中存储两种数据类型

c++ - 使用 -D_GLIBCXX_USE_CXX11_ABI=0 构建 boost

C++ 调用基类但返回派生类