gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 01:50:13 26 4
gpt4 key购买 nike

我想调用类的运行时绑定(bind)函数,这些函数从公共(public)类“Bindable”继承绑定(bind)能力。这真的可能吗?

这是一个肯定缺少大量模板参数和命名空间的 stub :

#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);
}

最佳答案

选项 #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;
}
};

DEMO 1

选项 #2

使用类型删除并使 bindFunction 成为函数模板:

struct Bindable {    
template <typename T, typename std::enable_if<std::is_base_of<Bindable, T>{}, int>::type = 0>
void bindFunction (int x, void(T::*newFn)()) {
mFns.insert(std::make_pair(x, std::bind(newFn, static_cast<T*>(this))));
}
void invokeFunction (int key) {
mFns.at(key)();
}
protected:
std::map<int, std::function<void()>> mFns;
};

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

DEMO 2

在这两种情况下,您都可以使用如下代码:

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);
}

输出:

called funAone
called funAtwo
called funBone
called funBtwo

关于c++11:子类成员函数的 std::bind,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27755699/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com