【问题标题】:std::bind and std::function overlap or complementary?std::bind 和 std::function 重叠还是互补?
【发布时间】:2013-12-24 09:07:48
【问题描述】:

我在看this exemple here,结合std::bind 和std::function 来创建一个命令:真漂亮!命令类的代码如下:

class Command
{
 private:
   std::function<void ()> _f;

 public:
   command() {}
   command(std::function<void ()> f) : _f(f) {}

   template <typename T> void setFunction (T t) {_f = t ;}
   void execute()
    {
        if(!_f.empty())
            _f();
    }
};

假设我有一个包含成员函数的类 MyClass

class MyClass
{
public:
    void myMemberFn() {}
}

那么调用代码如下:

MyClass myClass;

command(std::bind(&MyClass::myMemberFn, myClass));

虽然我必须承认我真的不明白为什么除了std::bind 之外还需要std::function。在我看来,bind 已经封装了函数调用,那为什么Command 中还需要函数呢?不能Commandstore std::bind 而不是std::function

我一直在查看 std::bindstd::function 的文档,但没有得到它......

有人知道为什么需要std::function吗?

PS: 我假设 std::bind ~= boost::bind 和 std::function ~= boost::function

【问题讨论】:

  • std::bind 是一个 function 模板,可用于复制初始化或分配给std::function,这是一个 class 模板。
  • setFunction 作为非模板void setFunction(std::function&lt;void()&gt; t) {_f = std::move(t);} 会更好。它并不比模板版本贵,而且由于move,它可能更便宜。
  • @Casey:很好的提示,谢谢!

标签: c++ boost c++11 stl


【解决方案1】:

您必须将std::bind 表达式的结果存储在某处。 std::bind 本身的返回类型未在标准中指定,因此您无法创建该类型的命名成员变量(不过,您可以使用 C++11 auto 来创建这样的局部变量!)

此外,任何采用std::function 的函数都可以(由于std::function 隐式转换)接受各种可调用对象,而不仅仅是std::bind 结果 - 您可以向其传递常规函数指针、lambda、自定义函数对象,任何可以调用的对象。

【讨论】:

  • 有一些模板技巧可以让你存储一个类型 T,其中 T 被推导出为 std::bind 的返回类型。
  • 此外,值得一提的是function 肯定有一些运行时开销。
【解决方案2】:

来自bind 文档,

A function object of unspecified type T, for which std::is_bind_expression<T>::value == true, 
and which can be stored in std::function.

所以

std::function<void ()> _f;

需要存储

的返回值
command(std::bind(&MyClass::myMemberFn, myClass));

以便以后可以实际调用。

【讨论】:

  • 谢谢,看起来很像!
猜你喜欢
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2016-12-18
  • 2019-02-20
  • 2021-09-18
相关资源
最近更新 更多