为什么 std::bind 在使用按引用传递时防止后期绑定?
Why does std::bind prevent late binding when using pass-by-reference?
我有一个基类,一个派生类和一个虚拟成员函数。我还有一个函数,它接受基类引用并对成员函数进行多态调用:
#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
。
为什么当我将按引用传递与std::bind
一起使用时会发生早期绑定,而不是其他方式?
std::bind
按值存储捕获的参数,从而导致Derived
的切片副本Base
。
如果您只是传递std::reference_wrapper
(指针)来复制指针,则不会发生切片复制:
std::function<int()> boundgetnumref = std::bind(getnumref, std::ref(bref));
更喜欢lambda,它们是最佳实践:更容易编写,阅读和更高效:
auto boundgetnumref = [&bref]() { return getnumref(breg); }
相关文章:
- 了解C++如何返回引用并绑定到引用
- 按值传递变量与按引用传递变量具有相同的结果
- C++通过绑定到引用成员而缩短临时变量寿命?
- C++初始化 std::function 时如何将占位符绑定到引用/引用参数?
- 获取 std::函数以推断按引用传递/按值传递
- C++/11 auto 关键字是在更有效时推导参数进行按引用传递,还是始终按值传递?
- 使用 enable_if 在按值传递与按引用传递之间更改函数声明
- 按引用传递和按地址传递之间的差异
- C++按引用传递还是按值传递?
- 可移动但不可复制的对象:按值传递还是按引用传递?
- 为什么"const auto [x, y]"绑定到引用类型时没有按预期运行?
- 使用增量运算符按引用传递
- C++函数,按引用传递
- 按引用传递和动态内存分配之间的区别是什么
- 通过查看程序集来比较按值传递与按引用传递性能
- 在形式参数列表中自动使用 const 和按引用传递的任何明显后果
- 结构化绑定和引用元组
- 按引用传递函数参数
- C 使用多个lambdas/绑定以引用相同的功能
- 为什么 std::bind 在使用按引用传递时防止后期绑定?