std::bind 在传递指针与引用时的行为不同

问题描述 投票:0回答:1

目标是让函子到达 Base::Print。

#include <functional>
#include <iostream>

using namespace std;
class Base {
 public:
  virtual void Print() {
      cout << "Base" << endl;
  }

  virtual function<void()> get_fx1() {
    return bind(&Base::Print, this);
  }

  virtual function<void()> get_fx2() {
    return bind(&Base::Print, *this);
  }
};

class Derived : public Base {
 public:
  virtual void Print() override {
    std::cout << "Derived" << std::endl;
  }
};

int main()
{
  Derived d;
  Base *ptr = &d;
  ptr->Base::Print();           // prints Base (expecetd) #out1
  bind(&Base::Print, ptr)();    // prints Derived (expected Base) #out2
  ptr->get_fx1()();             // prints Derived (expected Base) #out3
  ptr->get_fx2()();             // prints Base (expected Derived because of out2 and out3) #out4

  cout << " -- " << endl;
  Derived d2;
  Base& ref = d2;
  ref.Base::Print();            // prints Base (expected) #out5
  bind(&Base::Print, ref)();    // prints Base (expected Derived because of out2 and out3. But this matches the behaviour with out4) #out6

  cout << " -- " << endl;
  (&ref)->Base::Print();        // prints Base (expected) #out7
  bind(&Base::Print, &ref)();   // prints Derived (I give up) #out8
  
  return 0;
}

我假设传递指针或引用到 std::bind 是完全相同的。显然,我错了。似乎当引用传递给 std::bind 时,您可以阻止 vtable 查找。但是当指针传递给 std::bind 时,无法阻止 vtable 查找。根据经验,这就是看起来的样子。

所以,问题是:当传递引用时,std::bind 是否有选择地跳过 vtable 查找?

我没有找到任何参考资料仅说明这一点。

编辑: 链接到 编译器资源管理器

c++ vtable stdbind dynamic-dispatch
1个回答
0
投票

std::bind
无法绑定引用,您正在将派生类切片到基类,并在切片对象上调用虚函数。为此,虚拟调用正确调用了基类函数。

© www.soinside.com 2019 - 2024. All rights reserved.