c++ - std::bind 类成员函数

标签 c++ c++11

我有这个代码:

#include <iostream>
#include <functional>

struct Foo
{
        int get(int n) { return 5+n; }
};

int main()
{
        Foo foo;
        auto L = std::bind(&Foo::get, &foo, 3);

        std::cout << L() << std::endl;

        return 0;
}

似乎是这样的:

auto L = std::bind(&Foo::get, &foo, 3);

相当于:

auto L = std::bind(&Foo::get, foo, 3);

为什么?

最佳答案

std::bind() 按值 接受其参数。这意味着在第一种情况下,您将按值传递一个指针,从而得到一个指针的拷贝。在第二种情况下,您按值传递类型为 foo 的对象,从而生成类型为 Foo 的对象的拷贝。

因此,在第二种情况下,表达式 L() 的求值导致成员函数 get()copy 的原始对象 foo,它可能是也可能不是你想要的。

这个例子说明了区别(忘记违反三规则/五规则,这只是为了说明目的):

#include <iostream>
#include <functional>

struct Foo
{
    int _x;

    Foo(int x) : _x(x) { }

    Foo(Foo const& f) : _x(f._x)
    {
        std::cout << "Foo(Foo const&)" << std::endl;
    }

    int get(int n) { return _x + n; }
};

int main()
{
   Foo foo1(42);

   std::cout << "=== FIRST CALL ===" << std::endl;
   auto L1 = std::bind(&Foo::get, foo1, 3);
   foo1._x = 1729;
   std::cout << L1() << std::endl; // Prints 45

   Foo foo2(42);

   std::cout << "=== SECOND CALL ===" << std::endl;
   auto L2 = std::bind(&Foo::get, &foo2, 3);
   foo2._x = 1729;
   std::cout << L2() << std::endl; // Prints 1732
}

Live example .

如果出于任何原因不想使用指针形式,可以使用 std::ref()防止创建参数的拷贝:

auto L = std::bind(&Foo::get, std::ref(foo), 3);

关于c++ - std::bind 类成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16016112/

相关文章:

c++ - 透明的算子仿函数

c++ - 如何在 C++ 中使用 OpenGL 绘制 3D 超椭圆

c++ - 确定 OpenCV 中矩阵的类型

c++ - Qt转发信号/槽连接

c++ - 一个 const std::function 包装一个非常量 operator()/mutable lambda

c++ - 模板类型推导失败?

c++ - 将双 vector 拆分为相等的部分

c++ - 在 boost::python::import 期间和之后会发生什么?

c++ - 如何使用#ifdef 进行数据类型切换

c++ - 实例化不带参数的 C++ 模板类/取决于 if 语句中的类型