У меня есть базовый класс, производный класс и виртуальная функция-член. У меня также есть функция, которая берет ссылку на базовый класс и делает полиморфный вызов функции-члена:
#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
в современном коде, всегда предпочитайте лямбда-выражения. См.: youtu.be/zt7ThwVfap0?t=1754. - person Vittorio Romeo   schedule 28.09.2017