c++11:子类成员函数的std::bind

c++11:子类成员函数的std::bind,c++,c++11,C++,C++11,我想调用类的运行时绑定函数,这些类从一个公共的可绑定类继承绑定功能。这真的有可能吗 这里有一个存根,它肯定缺少很多模板参数和名称空间: #include <iostream> // std::cout #include <functional> // std::bind #include <map> // std::map class Bindable { public: void bindFunction (int x

我想调用类的运行时绑定函数,这些类从一个公共的可绑定类继承绑定功能。这真的有可能吗

这里有一个存根,它肯定缺少很多模板参数和名称空间:

#include <iostream>     // std::cout
#include <functional>   // std::bind
#include <map>          // std::map

class Bindable {
public:
    void bindFunction (int x, auto newFn) {
        mFns.insert(std::pair<int, auto>(x,newFn));
    }
    void invokeFunction (int key) {
        mFns.at(key)();
    }

protected:
    std::map<int, function> mFns;
};

class A : Bindable {
    void funAone (void) {
        cout << "called funAone" <<std::endl;
    }
    void funAtwo (void) {
        cout << "called funAtwo" <<std::endl;
    }
};

class B : Bindable {
    void funBone (void) {
        cout << "called funBone" <<std::endl;
    }
    void funBtwo (void) {
        cout << "called funBtwo" <<std::endl;
    }
};

int main() {
    A a;
    B b;

    a.bindFunction(1, &A::funAone);
    a.bindFunction(2, &A::funAtwo);
    b.bindFunction(1, &B::funBone);
    b.bindFunction(2, &B::funBtwo);

    a.invokeFunction(1);
    a.invokeFunction(2);
    b.invokeFunction(1);
    b.invokeFunction(2);
}

是的,这是可能的,使用std::bind。请注意,auto不能用作函数或模板参数

#include <iostream>     // std::cout
#include <functional>   // std::bind
#include <map>          // std::map

class Bindable {
public:
    typedef std::function<void()> Function;
    void bindFunction (int x, Function newFn) {
        mFns.insert(std::pair<int, Function>(x,newFn));
    }
    void invokeFunction (int key) {
        mFns.at(key)();
    }

protected:
    std::map<int, Function > mFns;
};

class A : public Bindable {
public:
    void funAone (void) {
        std::cout << "called funAone" <<std::endl;
    }
    void funAtwo (void) {
        std::cout << "called funAtwo" <<std::endl;
    }
};

class B : public Bindable {
public:
    void funBone (void) {
        std::cout << "called funBone" <<std::endl;
    }
    void funBtwo (void) {
        std::cout << "called funBtwo" <<std::endl;
    }
};

int main() {
    A a;
    B b;

    a.bindFunction(1, std::bind(&A::funAone, a)); // more than one way to bind
    a.bindFunction(2, std::bind(&A::funAtwo, &a)); // the object parameter
    b.bindFunction(1, std::bind(&B::funBone, b));
    b.bindFunction(2, std::bind(&B::funBtwo, &b));

    a.invokeFunction(1);
    a.invokeFunction(2);
    b.invokeFunction(1);
    b.invokeFunction(2);
}

是的,这是可能的,使用std::bind。请注意,auto不能用作函数或模板参数

#include <iostream>     // std::cout
#include <functional>   // std::bind
#include <map>          // std::map

class Bindable {
public:
    typedef std::function<void()> Function;
    void bindFunction (int x, Function newFn) {
        mFns.insert(std::pair<int, Function>(x,newFn));
    }
    void invokeFunction (int key) {
        mFns.at(key)();
    }

protected:
    std::map<int, Function > mFns;
};

class A : public Bindable {
public:
    void funAone (void) {
        std::cout << "called funAone" <<std::endl;
    }
    void funAtwo (void) {
        std::cout << "called funAtwo" <<std::endl;
    }
};

class B : public Bindable {
public:
    void funBone (void) {
        std::cout << "called funBone" <<std::endl;
    }
    void funBtwo (void) {
        std::cout << "called funBtwo" <<std::endl;
    }
};

int main() {
    A a;
    B b;

    a.bindFunction(1, std::bind(&A::funAone, a)); // more than one way to bind
    a.bindFunction(2, std::bind(&A::funAtwo, &a)); // the object parameter
    b.bindFunction(1, std::bind(&B::funBone, b));
    b.bindFunction(2, std::bind(&B::funBtwo, &b));

    a.invokeFunction(1);
    a.invokeFunction(2);
    b.invokeFunction(1);
    b.invokeFunction(2);
}
选择1 使用CRTP习惯用法了解可以存储哪些类型的成员函数指针:

template <typename T>
struct Bindable {   
    void bindFunction (int x, void(T::*newFn)()) {
        mFns.insert(std::make_pair(x,newFn));
    }
    void invokeFunction (int key) {
        (static_cast<T*>(this)->*mFns.at(key))();
    }

protected:
    std::map<int, void(T::*)()> mFns;
};

struct A : Bindable<A> {
    void funAone (void) {
        std::cout << "called funAone" <<std::endl;
    }
    void funAtwo (void) {
        std::cout << "called funAtwo" <<std::endl;
    }
};
在这两种情况下,您都可以按如下方式使用代码:

int main() {
    A a;
    B b;

    a.bindFunction(1, &A::funAone);
    a.bindFunction(2, &A::funAtwo);
    b.bindFunction(1, &B::funBone);
    b.bindFunction(2, &B::funBtwo);

    a.invokeFunction(1);
    a.invokeFunction(2);
    b.invokeFunction(1);
    b.invokeFunction(2);
}
输出:

选择1 使用CRTP习惯用法了解可以存储哪些类型的成员函数指针:

template <typename T>
struct Bindable {   
    void bindFunction (int x, void(T::*newFn)()) {
        mFns.insert(std::make_pair(x,newFn));
    }
    void invokeFunction (int key) {
        (static_cast<T*>(this)->*mFns.at(key))();
    }

protected:
    std::map<int, void(T::*)()> mFns;
};

struct A : Bindable<A> {
    void funAone (void) {
        std::cout << "called funAone" <<std::endl;
    }
    void funAtwo (void) {
        std::cout << "called funAtwo" <<std::endl;
    }
};
在这两种情况下,您都可以按如下方式使用代码:

int main() {
    A a;
    B b;

    a.bindFunction(1, &A::funAone);
    a.bindFunction(2, &A::funAtwo);
    b.bindFunction(1, &B::funBone);
    b.bindFunction(2, &B::funBtwo);

    a.invokeFunction(1);
    a.invokeFunction(2);
    b.invokeFunction(1);
    b.invokeFunction(2);
}
输出:


通过硬编码成员函数的签名并使用CRTP?谢谢,看起来不错!也许值得再问一个问题,但是:有没有办法在Bindable中的同一个std::map中存储具有不同签名的函数?你可以从我推导的第一个链接中找到答案和其他许多问题,我只是想让它硬编码成员函数的签名并使用CRTP?谢谢,看起来不错!也许值得再问一个问题,但是:有没有办法,要将具有不同签名的函数存储在Bindable中的同一个std::map中?您可以从我推导的第一个链接中找到答案和许多其他问题,只是为了在这里有它。出于什么原因,您将类更改为structs?@DPF只是为了在默认情况下使成员公开,并在默认情况下具有公共继承?出于什么原因您是否将类更改为structs?@DPF只是为了使成员在默认情况下是公共的,并在默认情况下具有公共继承