J'ai une classe de base, une classe dérivée et une fonction de membre virtuel. J'ai aussi une fonction qui prend une référence de classe de base et fait un appel polymorphes à la fonction membre:Pourquoi std :: bind évite-t-il une liaison tardive lors de l'utilisation d'une référence par renvoi?
#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;
}
Ici, la liaison tardive se produit, et la sortie est 2
.
Mais si j'ajoute maintenant les lignes suivantes à la fonction main()
afin de prédéfinir l'argument de la fonction, puis l'appeler:
std::function<int()> boundgetnumref = std::bind(getnumref, bref);
std::cout << boundgetnumref() << std::endl;
alors la sortie de la dernière ligne est 1
, c'est-à-dire que la liaison anticipée se produit ici et que la fonction membre de la classe de base est appelée.
Si j'utilise des pointeurs, à savoir
//...
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;
}
alors la sortie des deux appels cout
est 2
. Pourquoi une liaison précoce a-t-elle lieu lorsque j'utilise la référence de passage avec std::bind
, et pas autrement?
Légèrement sans lien: n'utilisez pas 'std :: bind' dans le code moderne, préférez toujours lambdas. Voir: https://youtu.be/zt7ThwVfap0?t=1754 –