1

我遇到了一些奇怪的行为。

这段代码给了我错误:

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 不接受类型名,它接受地址。

4

3 回答 3

0

我猜这个函数是静态的?如果没有解决方案,则需要调用一个对象。

但是 bind 试图在没有对象的情况下g使用参数调用"close",如果不是静态的则无法工作

于 2013-09-03T22:18:08.487 回答
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");

如图所示:http: //coliru.stacked-crooked.com/a/895584175a1a6a61

于 2013-09-03T23:03:07.480 回答
-1

对于任何试图做到这一点的人:

只需使用宏。如果没有自定义绑定实现,这几乎是不可能的。

#define BINDMF(a,b,c) (std::bind(&a::b, c))
于 2013-09-03T22:36:20.777 回答