记录一些奇妙的语言特性。

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