记录一些奇妙的语言特性。
std::bind
与多态性
将基类函数指针绑定到派生类对象上,调用时会调用派生类的函数。
#include <iostream>
#include <functional>
class Base
{
public:
virtual void print(){std::cout<<"Base"<<std::endl;}
};
class Child1 : public Base
{
public:
virtual void print() override { std::cout << "Child1" << std::endl; }
};
class Child2 : public Child1
{
public:
virtual void print() override { std::cout << "Child2" << std::endl; }
};
int main()
{
Base b;
Child1 c1;
Child2 c2;
std::bind(&Base::print, b)(); // Base
std::bind(&Base::print, c1)(); // Child1
std::bind(&Base::print, c2)(); // Child2
return 0;
}
当函数有重载时,需要通过static_cast指定函数指针类型,否则编译器无法确定调用哪个函数。
#include <iostream>
#include <functional>
class Base
{
public:
virtual void print() { std::cout << "Base" << std::endl; }
virtual void print(const int a) const { std::cout << "Base "<<a << std::endl; }
};
class Child: public Base
{
public:
virtual void print(const int a) const override { std::cout << "Child " << a << std::endl; }
};
int main()
{
Child c;
/// error: no instance of overloaded function "std::bind" matches the argument list
/// both candidate are rejected because at least one template argument could not be deduced
// std::bind(&Base::print, b)();
std::bind(static_cast<void(Base::*)()>(&Base::print), c)(); // Base
std::bind(static_cast<void(Base::*)(const int) const>(&Base::print), c, 1)(); // Child 1
std::bind(static_cast<void(Base::*)(const int) const>(&Base::print), c, std::placeholders::_1)(2); // Child 2
return 0;
}
模板参数传函数
例子:https://github.com/maki49/Flexible_Default