我有一个简单的调度程序结构,不会编译,说实话,我不知道为什么。
因此,我创建了一个调度程序,可以将一个函数绑定(bind)到名为update的调度程序,它将调用一个名为invoke的静态成员函数,该函数取消引用对象实例并使用简单的std::ostream
ref调用该方法。
由于某种原因,它无法编译,但对我来说似乎正确。
编译器不会给出任何好的输出:/
提前致谢
#include <iostream>
#include <list>
#include <utility>
namespace trd {
struct dispatcher {
public:
template<typename C, void(C::*M)(std::ostream & os) = C::update>
static void invoke(void * instance, std::ostream & os) {
(static_cast<C*>(instance)->*M)(os);
}
template<typename C, void(C::*M)(std::ostream & os) = &C::update>
void bind(C * instance) {
instances.push_back(std::make_pair(&invoke<C, M>, instance));
}
void operator () (std::ostream & os) {
for (auto & instance : instances)
(instance.first)(instance.second, os);
}
private:
std::list<std::pair<void(*)(std::ostream & os), void *>> instances;
};
}
struct test {
public:
void update(std::ostream & os) { os << "foo"; }
};
int main() {
trd::dispatcher dp;
test t;
dp.bind(&t);
dp(std::cout);
return 0;
}
最佳答案
您使用的是方法而不是函数,因此使用C样式强制转换将实例强制转换为void是不好的做法。
相反,C++具有std::function
和lambdas:
namespace trd {
struct dispatcher {
public:
template<typename C, void(C::*M)(std::ostream & os) = &C::update>
void bind(C * instance) {
instances.push_back([=](std::ostream & os){std::invoke(M, instance, os);});
}
void operator () (std::ostream & os) {
for (auto & instance : instances)
std::invoke(instance, os);
}
private:
std::list<std::function<void(std::ostream & os)>> instances;
};
}
使用C++ 17作为
std::invoke
。关于c++ - C++调度程序参数传递,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53747991/