C++ 一个更自然的选择?

C++ 一个更自然的选择?,c++,syntax,boost,signals,boost-bind,C++,Syntax,Boost,Signals,Boost Bind,别误会:Boost的bind()很棒 但我真的不喜欢用它来写和读代码,我已经放弃了希望我的同事们会使用它 我最终得到的代码如下: btn.clicked.connect(bind(&BetBar::placeBet, this, bet_id)); animator.eachFrame.connect(bind(&Widget::move, buttons[bet_id])); on(btn.clicked) placeBet(bet_id); on(animator.each

别误会:Boost的
bind()
很棒

但我真的不喜欢用它来写和读代码,我已经放弃了希望我的同事们会使用它

我最终得到的代码如下:

btn.clicked.connect(bind(&BetBar::placeBet, this, bet_id));
animator.eachFrame.connect(bind(&Widget::move, buttons[bet_id]));
on(btn.clicked) placeBet(bet_id);
on(animator.eachFrame) buttons[bet_id].move(eachFrame::newPos);
btn.clicked { |bet_id| placeBet bet_id }
animator.eachFrame { |newPos| buttons[bet_id].move newPos }
这虽然合乎逻辑,但与我所说的好代码相去甚远

证明。。。在C++1x中,我们将有:

btn.clicked.connect([&](int bet_id){ placeBet(bet_id); })
animator.eachFrame.connect([&](Point newPos) { buttons[bet_id].move(newPos) })
一个好的DSL可以是这样的:

btn.clicked.connect(bind(&BetBar::placeBet, this, bet_id));
animator.eachFrame.connect(bind(&Widget::move, buttons[bet_id]));
on(btn.clicked) placeBet(bet_id);
on(animator.eachFrame) buttons[bet_id].move(eachFrame::newPos);
btn.clicked { |bet_id| placeBet bet_id }
animator.eachFrame { |newPos| buttons[bet_id].move newPos }

<>强>你如何处理C++中的绑定?你是否只是靠着助推给你生活?< /强>

< p>我怀疑你在预0xC++中能得到更好的结果。Lambda或Phoenix提供了它们自己的绑定机制,但对于这种情况,它不会变得更具可读性,真的

如果你能想到如何在BC++中使用Booo::PROTO(有其他的替代方案)来编程这样的DSL,那么,你可以通过Boost邮件列表本身的其他原始成员得到更好的帮助,因为这将超出我的头脑。 对于同事来说:当他们在编程C++方面有专业性(读:他们得到报酬)时,他们要么去摸索,要么他们应该做另一个工作。如果他们不能阅读如此简单的结构,他们可能会产生更大的维护负担,然后他们可以通过帮助实现新功能来弥补


在这种情况下,为Lua(或您喜欢的任何脚本语言)提供一个良好的绑定,并让他们使用该语言执行业务逻辑。无论如何,这实际上是一个不错的解决方案。

看来您需要以下几点:

  • 隐式绑定到
  • 与存储绑定的函数调用关联的圆括号的替代项
  • 自动识别lambda表达式中绑定的参数

第一个在C++中非常困难,因为<>代码> 在非常少的上下文中是隐式的,当然不能将它隐式传递给函数。也就是说,不能用库函数来实现这一点,但可以用宏来实现。不过,这还是很难看的

第二部分要简单得多:

button.clicked.handler = bind(BetBar::placeBet, this, bet_id);
这只需要
handler.operator=(boost::function const&)

第三个也是很难的,因为您刚刚设计了另一个两阶段名称查找的案例。这对于模板来说已经够难了。boost的_1技巧通过明确哪些参数以后应该绑定而起作用。然而,作为一个名字并不神奇。它基本上是一个返回boost::arg的自由函数。因此,使用animator.eachFrame.newPos的适当定义,可以使以下内容等效:

animator.eachFrame.handler = bind(&Widget::move, buttons[bet_id], _1)
animator.eachFrame.handler = bind(&Widget::move, buttons[bet_id], animator.eachFrame.newPos)

作为旁注,实际上一个好的DSL看起来有点像这样:

btn.clicked.connect(bind(&BetBar::placeBet, this, bet_id));
animator.eachFrame.connect(bind(&Widget::move, buttons[bet_id]));
on(btn.clicked) placeBet(bet_id);
on(animator.eachFrame) buttons[bet_id].move(eachFrame::newPos);
btn.clicked { |bet_id| placeBet bet_id }
animator.eachFrame { |newPos| buttons[bet_id].move newPos }

回答您的问题:对于您提供的简单示例,一个简单的
bind
工作得很好。

proto看起来令人兴奋,我一定会深入研究它。谢谢