加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 回调中的std :: bind和std :: function用法

发布时间:2020-12-16 09:35:50 所属栏目:百科 来源:网络整理
导读:我试图理解事件处理/回调中的c 0x std :: bind和std :: function用法.所以我正在研究一些代码片段并遇到一些我无法完全理解的有趣的地方. 假设我们有: class EventHandler{public: templatetypename Event,typename Listener bool bindEvent (const Listene
我试图理解事件处理/回调中的c 0x std :: bind和std :: function用法.所以我正在研究一些代码片段并遇到一些我无法完全理解的有趣的地方.

假设我们有:

class EventHandler
{
public:
    template<typename Event,typename Listener>
    bool bindEvent (const Listener& function)
    {
        if (std::is_array<Event>::value)
        {
            std::cout << "You cannot register an array as an event type" << std::endl;
            return false;
        }
        if (std::is_convertible<Listener,std::function<void (Event&)>>::value)
        {
            std::cout << "Invalid callback for this event type" << std::endl;
            return false;
        }

        listeners.insert(std::make_pair(&typeid(typename std::decay<Event>::type),[=](void* ev) { function(*static_cast<Event*>(ev)); }));
    }
private:
    // for each event type,we have a list of callbacks
    // these callbacks are of the form std::function<void (void*)>
    // because we will convert between the &event and void*
    typedef std::function <void (void*)> fun;
    std::unordered_multimap <const std::type_info*,fun> listeners;
};

// example of an event type
struct KeyboardEvent
{
    int keyCode;
};

// example of an event callback
void do_key (const KeyboardEvent &event)
{
    std::cout << "I am working" << std::endl;
}

int main (int argc,char** argv)
{
    EventHandler handler;
    handler.bindEvent<KeyboardEvent> (&do_key);   // fixed typo

    return 0;
}

问题:Listener在这部分中使用什么类型?:

template<typename Event,typename Listener>
bool bindEvent(const Listener& function)

因为在main方法中我们只调用此函数.

PS:此外,此代码在std :: is_convertible部分失败. (据我所知,因为来自habindEvent< KeyboardEvent>(& do_key)的不匹配类型;

解决方法

监听器将被编译器推断为您传递它的函数指针的类型,在本例中为void(const KeyboardEvent&).

而你的测试失败了,因为它是错误的方式:你想要的

if (!std::is_convertible<Listener,std::function<void (Event&)>>::value)

相反(注意否定).

顺便说一句,std :: is_array和std :: is_convertable都是在编译时决定的,这意味着你正在使用运行时检查来确定静态的东西.相反,您可以使用SFINAE使模板无法绑定无效类型:

template<typename Event,typename Listener>
typename std::enable_if<!std::is_array<Event>::value && std::is_convertible<Listener,std::function<void(Event&)>>::value,bool>::type bindEvent (const Listener& function)
{
}

如果您尝试使用与您的条件不匹配的类型实例化模板,这将导致编译器错误.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读