c++ - 重新绑定(bind) std::function 的一个参数

标签 c++ c++11 stdbind

在我的 C++ 项目中,我决定尝试新的++ 功能。这些功能之一是将函数与 std::function 绑定(bind)通过std::bind .

现在我遇到一个用例,我必须重新绑定(bind) 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,它结合了(通过构造性实体几何)两个新对象(第 1 个小行星和第 2 个小行星):

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
}

因为 leftModelrightModel 必须是同一类的新模型,所以我需要重新绑定(bind)我之前在我的自动转译类Test::scene

也许我走错了路。我希望额外的上下文可以解释为什么我遇到了这个问题。

最佳答案

正如 @tobi303 和其他人所指出的,您的 second 参数的函数签名过于受限,因为它采用空函数。无需重新绑定(bind) - 它不带任何参数。

为了实现看起来像您正在尝试做的事情,您需要减少 second 的参数限制。有几种方法可以做到这一点(让它接受一个函数,或者一个指向成员函数的指针);下面显示了它由一个带有一元参数的函数模板参数化:

#include <functional>                                                                                                                           


using namespace std;


class Test
{   
public:
    void first()
    {   
        second([](Test *p){p->third();});
    }   

    template<class Fn> 
    void second(Fn fn) 
    {   
        Test *const other = new Test();
        fn(other);
    }   

    void third()
    {   
        // This is called in context of "other"
    }   
};  


int main()
{   
    Test t;
    t.first();
}   

个人观点(让我多次投反对票的观点):我认为使用了许多库和技术,大多数情况下 bind 是肯定的,大多数情况下是 function -只是在当前的 lambda 函数之前,对它们的需求越来越少。

关于c++ - 重新绑定(bind) std::function 的一个参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35506095/

相关文章:

c++ - 默认值和零初始化困惑

c++ - 使用 std::bind 时出现运行时错误

c++ - 如何声明实例化 `emplace()` 的 `std::set` 的返回?

c++ - 在 C++ 中在 map 的键上设置交集

c++ - 你能分配一个与 make_shared 等效的数组吗?

C++:获取 std::bind 产生的参数

c++ - std::bind 和函数模板

c++ - 指向其他结构数组元素的新手 C/C++ 结构数组

c++ - strcat 替代问题 C++

c++ - 对任意数量的可变参数应用函数