我遇到了一些奇怪的行为。
这段代码给了我错误:
struct Game {
void stop() {std::cout << "success\n";}
};
template<class ...Args>
struct holder {
std::map<std::string, std::function<void(Args...)>> funcMap;
template <typename T, typename U>
void connect(T* targObj, const std::string& funcName) {
std::function<void(Args...)> newFunc = std::bind(U, targObj);
//expected primary expression before ',' token on line above
funcMap[funcName] = newFunc;
}
void invoke(const std::string& funcName, class Args...Vals)
{funcMap[funcName](Vals...);}
};
int main() {
holder<> h;
Game g;
h.connect<Game, &Game::stop>(g, "close");
h.invoke();
}
std::bind
似乎不喜欢类型名作为输入。这有解决方法吗?手动使用具有相同参数的std::bind
可以正常工作,但它更多是样板代码:
std::function<void(Args...)> newFunc = std::bind(&ae::Game::stop, targObj);
即使没有任何输入,它仍然在编译时出错。为什么我的功能不起作用?
编辑:谢谢你的帮助。事实证明,bind不接受typename,它接受一个地址。答案 0 :(得分:0)
我猜这个功能是静态的吗? 如果没有解决方案,则需要调用一个对象。
但是bind试图在没有对象的情况下使用参数g
调用"close"
,如果不是静态则无法工作
答案 1 :(得分:0)
真的很简单:
template <typename T, typename U>
void connect(T* targObj, const std::string& funcName) {
T
和U
必须是类型,因为它们是类型模板。这个函数有点尴尬,它迫使人们写两个模板参数。
h.connect<Game, &Game::stop>(g, "close");
T=Game
,Game
是一种类型,所以这很好。 U=&Game::stop
,它是void (Game::*)()
的变量/实例,因此这是您失败的原因。我不知道为什么你的编译器会给出愚蠢的错误。解决方案是将函数变量作为参数传递:
template <typename T>
void connect(T* targObj, void(Game::func*)(Args...), const std::string& funcName)
并将其称为:
h.connect(g, &Game::stop, "close");
答案 2 :(得分:-1)
对于任何想要实现这一目标的人:
只需使用宏。如果没有自定义绑定实现,这几乎是不可能的。
#define BINDMF(a,b,c) (std::bind(&a::b, c))