【问题标题】:Why does std::bind prevent late binding when using pass-by-reference? [duplicate]为什么在使用传递引用时 std::bind 会阻止后期绑定? [复制]
【发布时间】:2017-09-28 11:52:55
【问题描述】:

我有一个基类、一个派生类和一个虚拟成员函数。我还有一个函数,它接受基类引用并对成员函数进行多态调用:

#include <iostream>
#include <functional>
class Base
{
public:
    Base() {}
    virtual int getnum() { return 1; }
};

class Derived : public Base
{
public:
    Derived() {}
    virtual int getnum() { return 2; }
};

int getnumref(Base& b) { return b.getnum(); }

int main()
{
    Derived d;
    Base& bref = d;
    std::cout << getnumref(bref) << std::endl;
}

这里发生了后期绑定,输出为2

但如果我现在将以下几行添加到main() 函数中,以便预先定义函数的参数,然后调用它:

std::function<int()> boundgetnumref = std::bind(getnumref, bref);
std::cout << boundgetnumref() << std::endl;

那么最后一行的输出是1,即这里发生了提前绑定,调用了基类的成员函数。

如果我使用指针,即

//...
int getnumptr(Base* b) { return b->getnum(); }
//...
int main()
{
    Derived d;
    Base* bptr = &d;
    std::cout << getnumptr(bptr) << std::endl;
    std::function<int()> boundgetnumptr = std::bind(getnumptr, bptr);
    std::cout << boundgetnumptr() << std::endl;
}

那么两个cout 调用的输出都是2

为什么当我将 pass-by-reference 与 std::bind 一起使用时会发生早期绑定,而不是其他情况?

【问题讨论】:

标签: c++ pass-by-reference std-function stdbind


【解决方案1】:

std::bind 按值存储捕获的参数,从而将Derived 的切片副本复制到Base

如果您只是传递将复制指针的std::reference_wrapper(一个指针),那么切片复制就不会发生:

std::function<int()> boundgetnumref = std::bind(getnumref, std::ref(bref));

虽然更喜欢 lambda,但它们是最佳实践:更容易编写、阅读和更高效:

auto boundgetnumref = [&bref]() { return getnumref(breg); }

【讨论】:

    猜你喜欢
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 2012-03-30
    相关资源
    最近更新 更多