矢量std :: function <>

Moo*_*ice 14 c++ hash function c++11

说要存储以下内容:

typedef std::function<void(int)> MyFunctionDecl;
Run Code Online (Sandbox Code Playgroud)

..收藏:

typedef std::vector<MyFunctionDecl> FunctionVector;
FunctionVector v;
Run Code Online (Sandbox Code Playgroud)

这是可能的,但如果我想找到一些东西std::find:

FunctionVector::const_iterator cit = std::find(v.begin(), v.end(), myFunctionDecl);
Run Code Online (Sandbox Code Playgroud)

..由于==操作员我们得到错误.

正如我之前在此问题中向我提出的那样,可以通过将函数声明封装在另一个类中来解决这个问题,该类提供了一个==运算符:

class Wrapper
{
private:
    MyFunctionDecl m_Func;

public:
    // ctor omitted for brevity

    bool operator == (const Wrapper& _rhs)
    {
         // are they equal?
    }; // eo ==
};  // eo class Wrapper
Run Code Online (Sandbox Code Playgroud)

所以我想要做的是以某种方式生成"MyFunctionDecl"的哈希,以便我可以正确实现==运算符.我可以拥有某种唯一标识符,并要求调用者为委托提供唯一标识符,但这看起来有点痛苦并且容易出错.

有没有办法可以做到这一点?为了比较的目的,相同的函数将返回相同的ID?到目前为止,绕过它的唯一方法是抛弃使用的概念std::function并返回使用支持比较的快速代理.但后来我失去了使用lambdas的能力.

任何帮助赞赏!

编辑

鉴于下面的答案,这就是我想出的......我可能错过的任何警告?我现在正在通过它的步伐:

class MORSE_API Event : boost::noncopyable
{
public:
    typedef std::function<void(const EventArgs&)> DelegateType;
    typedef boost::shared_ptr<DelegateType> DelegateDecl;

private:
    typedef std::set<DelegateDecl> DelegateSet;
    typedef DelegateSet::const_iterator DelegateSet_cit;
    DelegateSet m_Delegates;

public:
    Event()
    {
    };  // eo ctor


    Event(Event&& _rhs) : m_Delegates(std::move(_rhs.m_Delegates))
    {
    };  // eo mtor

    ~Event()
    {
    };  // eo dtor

    // methods
    void invoke(const EventArgs& _args)
    {
        std::for_each(m_Delegates.begin(),
                      m_Delegates.end(),
                      [&_args](const DelegateDecl& _decl) { (*_decl)(_args); });
    };  // eo invoke

    DelegateDecl addListener(DelegateType f)
    {
        DelegateDecl ret(new DelegateType(f));
        m_Delegates.insert(ret);
        return ret;
    };  // eo addListener

    void removeListener(const DelegateDecl _decl)
    {
        DelegateSet_cit cit(m_Delegates.find(_decl));
        if(cit != m_Delegates.end())
            m_Delegates.erase(cit);
    };  // eo removeListener

};  // eo class Event
Run Code Online (Sandbox Code Playgroud)

Giu*_*ano 7

你看过Boost Signals吗?它可能已经在做你想做的事情.

无论如何,一个简单的包装方式function是使用a shared_ptr.如果你这样做

typedef std::shared_ptr<std::function<void(int)> > MyFunctionDecl;
Run Code Online (Sandbox Code Playgroud)

并确保函数shared_ptr在创建时立即包装在内部(以便指针是唯一的),可以测试指针的相等性,这样std::find就可以了.

例如,你可以使用像这样的工厂函数

template <class Functor>
MyFunctionDecl createDelegate(Functor f) {
    return MyFunctionDecl(new std::function<void(int)>(f));
}
Run Code Online (Sandbox Code Playgroud)

这样,在创建委托时,您可以为函数(其指针)指定唯一标识.

顺便说一句,我会使用一个std::set,而不是一个std::vector,因为这两个finderase是对数的,而不是线性的.