在我的解释器中绑定嵌套函数的更好方法
Better way to bind nested functions in my interpreter
我正在尝试编写一个解释器,该解释器将转换如下字符串:
vector(random(0, 1), 2, 3)
使用类似boost::bind
的转换为绑定函数
bind(&vector, bind(&random, 0, 1), 2, 3)
预期用途是粒子系统,所以我希望能够将粒子传递给这些系统,这是通过添加类似λ的来实现的
bind(&vector, bind(&random, 0, 1, _1), 2, 3, _1)
然后将这些绑定函数定义为:typedef boost::function<boost::any(Particle*)> bound_particle_func;
,所以我可以形成一个函数调用列表,将每个粒子传递到该列表,以操纵它们的行为,从而创建效果。
我可以很容易地让解释器处理类似vector(1, 2, 3)
的东西,但当涉及到嵌套函数时,事情变得一团糟,我觉得我在处理事情。
因为解析器目前以递归方式处理嵌套函数,所以我不能直接将lambda值绑定到嵌入函数。
所以与其以bind(&vector, bind(&random, 0, 1, _1), 2, 3, _1)
事实上,我最终CCD_ 8不传递粒子的束缚函数。
我不知道如何更好地处理嵌套函数。
我目前拥有的实际代码(不可编译)是:
typedef std::vector<Token>::iterator token_it;
typedef boost::function<boost::any(Particle*)> bound_particle_func;
Vector3 vector(float x, float y, float z, Particle* p = 0);
bound_particle_func parse(token_it& it);
bound_particle_func ParseVector(std::vector<Token>& tokens) {
const static int arg_count = 3;
std::vector<boost::variant<float, bound_particle_func>> args(arg_count);
int type[] = { 0, 0, 0 };
for(token_it it = tokens.begin(); it != tokens.end(); ++it) {
Token& t = *it;
if(t.type == Type::FLOAT) {
args.push_back(t.float_value);
} else if(t.type == Type::FUNCTION) {
args.push_back(parse(it));
type[args.size() - 1] = 1;
} else {
throw std::runtime_error("Type error: expected float");
}
if(args.size() > arg_count) {
throw std::runtime_error("Too many arguments for function `vector`");
}
}
return boost::bind(&vector, (type[0] == 0 ? boost::get<float>(args[0]) : boost::get<bound_particle_func>(args[0])),
(type[1] == 0 ? boost::get<float>(args[1]) : boost::get<bound_particle_func>(args[1])),
(type[2] == 0 ? boost::get<float>(args[2]) : boost::get<bound_particle_func>(args[2])),
boost::lambda::_1);
}
bound_particle_func parse(token_it& it);
函数只是将相关令牌传递给适当的函数,如上面的函数。
请勿使用boost::function
或boost::bind
。不能将boost::function
传递给需要int
的对象。
由于您只需要一种类型的延迟参数,并且需要将其传递给所有函数,因此滚动自己的函数对象要容易得多。
使用boost::function
和boost::bind
的另一种选择是使用类似的东西:
Vector3 f_vector(bound_particle_func x, bound_particle_func y,
bound_particle_func z, Particle* p = 0)
{
return vector (boost::get<float>(x(p)), boost::get<float>(y(p)),
boost::get<float>(z(p)), p);
}
其他功能也是如此。数字由绑定函数表示,这些函数只返回其绑定的float
参数,而忽略其Particle*
参数。
- 初始化具有非默认构造函数的std::数组项的更好方法
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 对于等待以 std::future wait() 返回的函数的 CPU 使用率或检查标志在循环中休眠一段时间哪个更好?
- 在类的第一个/最后一个实例存在之前/之后调用一对函数.有没有更好的方法?
- 使用构造函数初始化结构还是在之后设置其值更好?
- 对于可移动类型,按值传递比重载函数更好吗?
- 函数的返回是 LPVOID 或更好的指向列表的指针
- 重新定义要在函数中使用的静态变量 - 有没有更好的方法?
- 除了使用 clock() 函数之外,有没有更好的方法来以给定的频率生成/发布数据
- 在构造函数中组织初始值设定项列表的更好方法
- 使用成员函数更改对象或返回并分配它是否被认为是更好的做法?
- 需要一种更好的方法来编写电源函数
- 哪种 c++ 构造函数样式更好
- 有没有更好的方法可以从静态和非静态函数返回相同的字符串文本
- Curly Braces构造函数更喜欢initializer_list而不是更好的匹配.为什么
- 哪一个更好?使用C 代码中的System()函数或使用源代码
- 这是检查 const 函数(如果是否创建某些内容)的更好方法
- 为白名单类型约束模板函数的更好方法,SFINAE
- 调用包含所有所需代码的函数或内部包含所需代码的其他函数的函数更好?
- 是将基类强制转换为派生类更好,还是在基类上创建一个虚拟函数更好