鉴于以下内容,"功能"?

时间:2015-04-14 15:40:45

标签: c++ lambda std-function

鉴于以下内容,"功能"?

#include <functional>
#include <vector>

template<class T>
class Foo
{
public:

    template<typename P, typename Q, typename R, typename... Args>
    void Attach(P (Q::*f)(Args...), R p)
    {
        auto function = [p, f](Args... args)
        {
            (*p.*f)(args...);
        };

        Listeners.push_back(function);
    }   

private:

    std::vector<std::function<T>> Listeners;
};

class Bar
{
public:

    int Handler(int x, int y, int z)
    {
        return 0;
    }
};

int main(void)
{
    auto foo = Foo<int(int, int, int)>();
    auto bar = Bar();

    foo.Attach(&Bar::Handler, &bar);
}

对于某些上下文,我尝试创建一个调用实例上方法的lambda,将该lambda存储到集合中。我的push_back无法编译,出现以下错误:

  

xrefwrap(283):错误C2440:&#39;返回&#39; :无法转换为&#39; void&#39;至   &#39; INT&#39;

我最初使用std :: bind来创建一个我可以存储的std :: function。显然我可以用lambda(和可变参数模板,所以我不需要每个模板一个模板),但到目前为止,它击败了我。

1 个答案:

答案 0 :(得分:6)

构建Foo后,提供的显式模板参数为auto foo = Foo<int(int, int, int)>();

int main(void)
{
    auto foo = Foo<int(int, int, int)>(); //<<<< Here is the template arguments when constructing Foo 
    auto bar = Bar();

    foo.Attach(&Bar::Handler, &bar);
}

当您注册监听器时,函数签名返回类型为void

auto function = [p, f](Args... args)
    {
        (*p.*f)(args...);
    };

分辨率

所以要么你

  • 更改Foo的显式模板参数,auto foo = Foo<void(int, int, int)>();返回void以匹配您的侦听器回调。
  • 或确保您的侦听器函数返回一个整数。 return (*p.*f)(args...);

注意您可能打算从侦听器返回状态代码,但您可能错过了?所以第二个解决方案点在我看来是一个明显合理的问题