标签: stdbind

使用std :: function和std :: bind来存储回调并处理对象删除.

我想实现一个管理器,它使用C++ 11将回调存储到多态类的成员函数中.问题是我不知道如何处理成员所属的对象被删除或应该被删除的情况,我想让界面尽可能简单.

所以我想到了以下内容:将a存储std::weak_ptr到对象以及存储std::function到成员.

以下似乎有效:

class MyBase {
public:
    MyBase() {}
    virtual ~MyBase() {}
};
//--------------------------------------------------

class MyClass : public MyBase {
public:
    MyClass() : MyBase() {}
    void myDouble(double val) const { std::cout << "Value is: " << val << std::endl; }
};
//--------------------------------------------------

Class Manager {
public:
    void setFunction(std::weak_ptr<MyBase> base, std::function<void(double)> func) {
        m_function.first  = base;
        m_function.second = func;
    }
private:
    std::pair<std::weak_ptr<MyBase>, std::function<void(double)>> m_function;
};
Run Code Online (Sandbox Code Playgroud)

要使用它:

Manager db;
std::shared_ptr<MyClass> myClass = std::make_shared<MyClass>();
db.setFunction(myClass, std::bind(&MyClass::myDouble, myClass, std::placeholders::_1)); …
Run Code Online (Sandbox Code Playgroud)

c++ stdbind c++11 std-function

10
推荐指数
1
解决办法
1827
查看次数

了解std :: function和std :: bind

我正在玩std :: function和std :: bind,我注意到一些不直观的东西,我想更好地理解它.

例如:

void fun()
{
}

void hun(std::string) 
{ 
}

int main()
{

   function<void(int)> g = &fun; //This fails as it should in my understanding.

   function<void(int)> f = std::bind(fun); //This works for reasons unknown to me     
   function<void(int, std::string)> h = std::bind(hun); //this doesn't work

return 0;
}
Run Code Online (Sandbox Code Playgroud)

如何function<void(int)>将一个函数绑定到void().然后我可以调用f(1)并获得乐趣().我想了解这是如何完成的.进入微软Visual Studio 2012的实现,让我迷失在无法理解的宏观之中.所以这就是我在这里问这个问题的原因.

c++ stdbind c++11 std-function

9
推荐指数
2
解决办法
1778
查看次数

使用std :: bind时,为什么复制ctor被调用了两次?

我正在玩,std::functionstd::bind了解如何复制参数,如果我可以保存一些复制操作.

我理解在使用时std::bind,参数是通过值传递而不是引用(除非std::ref指定).但是,当我运行以下代码段时,复制构造函数被调用两次.有人可以解释原因吗?

struct token
{
    static int i;
    int code;

    token()
        : code(i++)
    {
        cout << __FUNCTION__ << ": " << code << endl;
    }
    virtual ~token()
    {
        cout << __FUNCTION__ << endl;
    }

    token (token const & other)
        : code (other.code)
    {
        cout << "copy ctor: " << code << endl;
    }

    // update -- adding a move ctor
    token (token const && other)
        : code (std::move(other.code))
    {
        cout << "move …
Run Code Online (Sandbox Code Playgroud)

c++ stdbind std-function

9
推荐指数
1
解决办法
229
查看次数

mem_fn和bind的一些实际用途

有人可以推荐tr1的mem_fn和绑定工具的一些很酷的实际用途吗?我不需要深奥的c ++用于库开发.只是一些使用这些的应用程序级编码.

任何帮助将非常感激.

c++ tr1 mem-fun stdbind

8
推荐指数
2
解决办法
6637
查看次数

std :: async使用绑定到lambda的rvalue引用

我正在尝试将一个rvalue引用绑定到一个lambda使用std::bind,但是当我把它扔进一个std::async调用时我遇到了问题:( 来源)

auto lambda = [] (std::string&& message) {
    std::cout << message << std::endl;
};
auto bound = std::bind(lambda, std::string{"hello world"});
auto future = std::async(bound); // Compiler error here
future.get()
Run Code Online (Sandbox Code Playgroud)

这会发出编译器错误我不确定如何解释:

错误:'class std :: result_of(std :: basic_string)>&()>'中没有​​名为'type'的类型

这里发生了什么?有趣的是,稍微修改确实可以按预期编译和工作.如果我改为std::string{"hello world"}c字符串文字,一切正常:( 来源)

auto lambda = [] (std::string&& message) {
    std::cout << message << std::endl;
};
auto bound = std::bind(lambda, "hello world");
auto future = std::async(bound);
future.get(); // Prints "hello world" as expected
Run Code Online (Sandbox Code Playgroud)

为什么这有效但不是第一个例子?

c++ lambda stdbind c++11

8
推荐指数
1
解决办法
502
查看次数

包装rvalue引用lambda时std :: async和std :: bind之间的区别

受此评论的启发,关于将lambda与rvalue引用参数直接std::async绑定到,通过std::async编译将rvalue绑定到lambda 并按预期执行:( 实例)

auto lambda = [] (std::string&& message) {
    std::cout << message << std::endl;
};
auto future = std::async(lambda, std::string{"hello world"});
future.get();
Run Code Online (Sandbox Code Playgroud)

std::bind但是,使用会触发编译器错误:( 实例)

auto lambda = [] (std::string&& message) {
    std::cout << message << std::endl;
};
auto bound = std::bind(lambda, std::string{"hello world"}); // Compiler error
bound();
Run Code Online (Sandbox Code Playgroud)

这是因为std::bind保持message为左值,因此当它将它传递给lambda时,参数不再与参数匹配.

我已经阅读std::async内部使用的内容std::bind,那么当std::bind它没有时,如何使用rvalue引用参数?是否存在需要此行为的标准的特定部分,或者这取决于编译器?

c++ lambda rvalue-reference stdbind c++11

8
推荐指数
1
解决办法
367
查看次数

将std :: bind与重载函数一起使用

我无法找到如何使用参数将参数绑定到重载函数std::bind.不知何故std::bind不能推断出重载类型(对于它的模板参数).如果我不重载该功能一切正常.代码如下:

#include <iostream>
#include <functional>
#include <cmath>

using namespace std;
using namespace std::placeholders;

double f(double x) 
{
    return x;
}

// std::bind works if this overloaded is commented out
float f(float x) 
{
    return x;
}

// want to bind to `f(2)`, for the double(double) version

int main()
{

    // none of the lines below compile:

    // auto f_binder = std::bind(f, static_cast<double>(2));

    // auto f_binder = bind((std::function<double(double)>)f, \
    //  static_cast<double>(2));

    // auto f_binder = bind<std::function<double(double)>>(f, \ …
Run Code Online (Sandbox Code Playgroud)

c++ overloading stdbind c++11

7
推荐指数
1
解决办法
3772
查看次数

如何在 C++ 中使用 std::bind 函数作为信号处理程序?

我正在使用以下代码向我的 C++ 类添加信号处理:

namespace {
    std::atomic<bool> signal_flag(false);   
}
void terminate_or_interrupt_handler(int signal) {
    switch (signal) {
        case SIGTERM:
            WARN("SIGTERM received");
            signal_flag.store(true);
            break;
        case SIGINT:
            WARN("SIGINT received");
            signal_flag.store(true);
            break;
        default:
            throw (std::runtime_error("Unhandled signal received"));
    }
}
signal(SIGTERM, &terminate_or_interrupt_handler);
Run Code Online (Sandbox Code Playgroud)

此代码有效,但它需要在与信号标志变量相同的范围内定义信号处理函数。我决定修改代码并将通过signal_flag引用传递给函数并用于std::bind将处理程序“专门化”到我的类。

 void terminate_or_interrupt_handler(std::atomic<bool>& signal_flag, int signal) {
    switch (signal) {
        case SIGTERM:
            WARN("SIGTERM received");
            signal_flag.store(true);
            break;
        case SIGINT:
            WARN("SIGINT received");
            signal_flag.store(true);
            break;
        default:
            throw (std::runtime_error("Unhandled signal received"));
    }
}
auto my_handler = std::bind(terminate_or_interrupt_handler, std::ref(my_class_signal_flag), std::placeholders::_1);
signal(SIGTERM, &my_handler);
Run Code Online (Sandbox Code Playgroud)

但是,我收到此编译错误:

error: cannot …
Run Code Online (Sandbox Code Playgroud)

c++ signals stdbind

7
推荐指数
1
解决办法
2358
查看次数

为什么我可以使用错误的参数进行 std::bind 成功?

#include <iostream>
#include <functional>

using callback = std::function<void(int, void*)>;

void AddCallback(callback cb) {}

void foo(int i) {}

int main() {
  auto f = std::bind(&foo, std::placeholders::_1);
  AddCallback(f);
}
Run Code Online (Sandbox Code Playgroud)

我用 g++ 9.3.0 和 clang++ 10.0.0 尝试了代码,它们都编译结束没有错误。

绑定结果和回调的类型是否相同?一个是std::function<void(int, void*)>,另一个是等于std::function<void(int)>什么?为什么我可以AddCallback()用不同的类型调用?

c++ stdbind c++11

7
推荐指数
1
解决办法
138
查看次数

为什么在构造函数中调用虚拟方法并绑定虚拟方法然后稍后调用它会产生不同的结果?

这是我的代码片段:

class Base {
  public:

  Base() {
    foo();
    bind();
  }

  virtual void foo() {
    std::cout << "base foo\n";
  }

  void bind() {
    fn = std::bind(&Base::foo, this);
  };

  std::function<void()> fn;
};

class Derived : public Base {
  public:

  void foo() override {
    std::cout << "derived foo\n";
  }

  void bind()  {
  }

  int val;    
};

int main() {
  Base* p = new Derived();
  p->fn();
}
Run Code Online (Sandbox Code Playgroud)

输出是:

class Base {
  public:

  Base() {
    foo();
    bind();
  }

  virtual void foo() {
    std::cout << "base …
Run Code Online (Sandbox Code Playgroud)

c++ constructor virtual-functions stdbind

7
推荐指数
2
解决办法
148
查看次数