有没有任何一种"表达类"(C++)

18 c++ expression

我正在创建一个游戏,让玩家输入输入,更改某些状态,然后检查"目标值"是否为真(显然这个描述非常简化),并且我希望能够将目标值设置为if如果剩余的敌人数量等于零,则玩家的生命低于某个值.是否有任何"表达式类"可以保存一个简单的"value1比较运算符值2"并检查它?即:

expression goal(x = 4);
Run Code Online (Sandbox Code Playgroud)

如果没有,是否有人建议如何开发表达式类?

编辑:另一个(更多的是我想要实现的)示例:

game.init(){ expression goal = FileRead(goalfile); }
game.checkstate(){ if(goal) exit(1); } //exit 1 is the games win state

//another more specific eg.:
class level1 { public: expression goal(total_enemies == 0); };
class level2 { public: expression goal(player.x == goal.x && player.y == goal.y); };
Run Code Online (Sandbox Code Playgroud)

Mac*_*cke 22

动态表达

如果你想从用户那里收到一个字符串并从中构建一个表达式,那么C++数学表达式库可能适合您的账单吗?

template<typename T>
void trig_function()
{
   std::string expression_string = "clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)";
   T x;
   exprtk::symbol_table<T> symbol_table;
   symbol_table.add_variable("x",x);
   symbol_table.add_constants();

   exprtk::expression<T> expression;
   expression.register_symbol_table(symbol_table);

   exprtk::parser<T> parser;
   parser.compile(expression_string,expression);

   for (x = T(-5.0); x <= T(+5.0); x += 0.001)
   {
      T y = expression.value();
      printf("%19.15f\t%19.15f\n",x,y);
   }
}
Run Code Online (Sandbox Code Playgroud)

还有可能嵌入脚本语言,例如LuaPython,它将为您提供(甚至)更多功能.如果您正在编写游戏,则需要考虑这一点,因为您可能希望编写大部分内容.

如果您正在使用Qt,则可以使用QtScript(Javascript-ish)运行从QObject派生对象读取(静态或动态)属性的表达式.

使用上面的一个使你不必编写自己的解析器,AST和评估器,但是对于一小组操作符,如果你使用Boost.Spirit或其他一些像样的解析库,那么攻击它们应该不会太难.

静态表达式

要在一组预定义表达式之间进行选择(即在编译时已知),您应该将表达式存储在多态函数对象中.

对于C++ 11,如果您可以使用它,请使用std::function和lambda表达式.

std::function<bool (int, int)> expr = [](int a, int b) { a*2 < b };
Run Code Online (Sandbox Code Playgroud)

对于早期的编译器,我推荐使用函数和绑定,在Boost(boost::)或C++ 0x TR1(std::)中,具体取决于您的编译器.此外,Boost.Lambda将在这里提供帮助,因为它允许您构造和存储表达式以供以后评估.但是,如果您不熟悉C++和模板(或函数式编程),它可能会让您感到非常恐慌.

有了这个,你可以写

using namespace boost::lambda;
boost::function<bool (int, int)> myexpr1 = (_1 + _2) > 20;
boost::function<bool (int, int)> myexpr2 = (_1 * _2) > 42;
std::cout << myexpr1(4,7) << " " << myexpr2(2,5);
Run Code Online (Sandbox Code Playgroud)

与绑定,它看起来像:

boost::function<bool (Player&)> check = bind(&Player::getHealth, _1) > 20;
Player p1;
if (check(p1)) { dostuff(); }

check = bind(&Player::getGold, _1) < 42;
if (check(p1)) { doOtherStuff(); }
Run Code Online (Sandbox Code Playgroud)