C++ C+中的泛型函数指针+;11

C++ C+中的泛型函数指针+;11,c++,c++11,function-pointers,C++,C++11,Function Pointers,我目前正在用C++x0编写一个方法执行队列。我已经实现并验证了基本队列机制,但希望通过一个选项对其进行修改,使push()自动删除以前对特定方法的所有调用: queue.push(this, &Obj::foo, 1); queue.push(this, &Obj::foo, 2); queue.push(this, &Obj::foo, 3); 应该和打电话一样 queue.push(this, &Obj::foo, 3); 到目前为止,我的代码如下所示:

我目前正在用C++x0编写一个方法执行队列。我已经实现并验证了基本队列机制,但希望通过一个选项对其进行修改,使
push()
自动删除以前对特定方法的所有调用:

queue.push(this, &Obj::foo, 1);
queue.push(this, &Obj::foo, 2);
queue.push(this, &Obj::foo, 3);
应该和打电话一样

queue.push(this, &Obj::foo, 3);
到目前为止,我的代码如下所示:

队列.h:

#pragma once

#include <functional>
#include <vector>

using std::vector;
using std::function;
using std::bind;

class Queue
{

    private:
        struct functioncall {
            std::function<void()> call;
        };

        vector<functioncall> queue;

    public:
        Queue();
        ~Queue();

        template<typename T, typename F, typename... Args>
        int push(T, F , Args... args);

        int pop();
        bool empty();
        size_t size();
};


template<typename T, typename F, typename... Args>
int Queue::push(T instance, F func, Args... args)
{
    functioncall newelem = { bind(func, instance, args...) };
    queue.push_back(newelem);
    return queue.size();
}
我已经准备好向量
队列
来获取一个结构,我不仅要保存
std::bind
的结果,还要保存指向正在调用的方法的指针,这样我就可以查找该指针并删除旧条目


问题是传递给
push()
的函数可以接受任意数量的参数。是否有一种通用指针类型(它不必是可执行的,只要在我反复将同一个函数推送到队列时保持相同)可以做到这一点?

根据5.2.10p10,您可以将指向成员函数的指针转换为指向成员函数类型的另一个指针
U:*(B1,…)
返回,信息不丢失
std::less
可以比较指向成员函数的指针,因此通过强制转换到指向成员类型的伪指针
void(Impl::*)()
可以比较指向具有相同签名的成员函数的指针

但是,不能保证具有不同签名的成员函数指针在强制转换为相同的成员类型指针时会比较不同,因此需要将签名编码为可比较的类型<代码>类型ID将在此处工作:

auto key = std::make_pair(&typeid(F), reinterpret_cast<void (Queue::*)()>(func));
auto key=std::make_pair(&typeid(F),reinterpret_cast(func));
这假设
F
确实是一个指向成员函数的指针;如果用户试图传递其他可调用对象,则此操作将中断。

可用于检查包装的函数类型:

template <class F> bool is_same_call(const functionalcall& prevCall, F newCall)
{
   const F* pf = prevCall.call.target<F>();
   return pf ? *pf == newCall : false;
}
模板bool是相同的调用(const functionalcall&prevCall,F newCall)
{
常量F*pf=prevCall.call.target();
返回pf?*pf==newCall:false;
}
请注意,如果使用
std::function
对象包装的函数的类型与
F
不同,则
std::function::target()
将返回
nullptr

template <class F> bool is_same_call(const functionalcall& prevCall, F newCall)
{
   const F* pf = prevCall.call.target<F>();
   return pf ? *pf == newCall : false;
}