【发布时间】:2016-02-19 13:06:40
【问题描述】:
在我的 C++ 项目中,我决定尝试新的 ++ 功能。其中一项功能是通过std::bind 将函数与std::function 绑定。
现在我遇到了一个用例,我必须重新绑定std::function。
考虑以下简化代码:
class Test
{
public:
void first()
{
second(bind(&Test::third, this));
}
void second(function<void()> fun)
{
Test *other = new Test();
fun->rebindLastParameter(other); // How can I do this?
fun();
}
void third()
{
// This is called in context of "other"
}
}
我该如何做fun->rebindLastParameter(other); 部分(将this 指针替换为other)?
(编辑)上下文:
在我的应用程序中有几个类继承自一个名为BaseModel 的类。这些类是从自制的描述语言自动转换而来的。下面的类代表一个简单的“小行星”,它由另外两个“小行星”组成:
#pragma once
#include "BaseModel.h"
#include <functional>
using namespace std;
using namespace std::placeholders;
class Test : public BaseModel
{
public:
Test(const OBB& start_obb) : BaseModel(start_obb) {}
void __init() {
scene();
}
void scene() {
combine(bind(&Test::asteroid, this),bind(&Test::asteroid, this));
}
void asteroid() {
translate(random_float(),random_float(),random_float());
sphere(7);
repeat(400,bind(&Test::impact, this));
}
void impact() {
auto p1 = random_surface_point();
select_sphere(p1,random_float() * 2 + 1,1.0);
normalize(p1);
translate_selection(-p1 * random_float() * 0.4);
}
};
问题在于函数BaseModel::combine,它结合(通过构造立体几何)两个新物体(第一个小行星和第二个小行星):
void BaseModel::combine(function<void()> left, function<void()> right)
{
BaseModel *leftModel = (BaseModel*) ::operator new (sizeof(BaseModel));
BaseModel *rightModel = (BaseModel*) ::operator new (sizeof(BaseModel));
leftModel->initWithStartOBB(*this->obb);
rightModel->initWithStartOBB(*this->obb);
auto newLeft = bind(left, leftModel); // This does not work
auto newRight = bind(right, rightModel); // This does not work
newLeft();
newRight();
// ... CSG stuff
}
由于leftModel 和rightModel 必须是同一类的新模型,我需要重新绑定我之前在自动转译类Test::scene 中提供的第一个参数。
也许我走错了路。我希望其他上下文可以解释我遇到这个问题的原因。
【问题讨论】:
-
third()不带任何参数,为什么要在这里使用bind? -
@tobi303
third()是一个成员函数,因此第一个参数始终是执行它的Test对象的指针。 -
@Timm:请提供更多信息,因为不清楚您想要实现什么
-
@SimonKraemer 是的,我知道,但是我可能会简单地调用具有不同对象的方法,而不是
bind不同对象的方法 -
即使忽略
third是一个类方法这一事实,我也不明白为什么需要“重新绑定”。只需通过将third绑定到其他参数来创建另一个function,您不必重用旧函数。