C++11 中的通用函数指针

Nil*_*ner 5 c++ function-pointers c++11

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

queue.push(this, &Obj::foo, 1);
queue.push(this, &Obj::foo, 2);
queue.push(this, &Obj::foo, 3);
Run Code Online (Sandbox Code Playgroud)

应该与仅仅调用相同

queue.push(this, &Obj::foo, 3);
Run Code Online (Sandbox Code Playgroud)

到目前为止我的代码如下所示:

队列.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();
}
Run Code Online (Sandbox Code Playgroud)

队列.cpp:

#include "Queue.h"

Queue::Queue() : queue()
{
}

Queue::~Queue()
{
    delete &queue;
}

int Queue::pop()
{
    if(!queue.empty())
    {
        queue.front().call();
        queue.erase(queue.begin());
        return queue.size();
    }
    return 0;
}

bool Queue::empty()
{
    return queue.empty();
}

size_t Queue::size()
{
    return queue.size();
}
Run Code Online (Sandbox Code Playgroud)

我已经准备好了向量queue来获取一个结构,我不仅想保存结果std::bind,还想保存指向被调用方法的指针,这样我就可以查找该指针并删除旧条目。

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

eca*_*mur 5

根据 5.2.10p10,您可以将一个指向成员函数的指针转换T::*(A1, A2, ...)为另一个指向成员函数类型的指针U::*(B1, ...),并返回,而不会丢失信息;std::less可以通过转换为指向成员的虚拟指针类型来比较指向成员函数的指针void (Impl::*)()您可以比较指向具有相同签名的成员函数的指针。

但是,不能保证指向具有不同签名的成员函数的指针在转换为相同的指向成员类型的指针时会比较不同,因此您需要在可比较类型中对签名进行编码。 typeid将在这里工作:

auto key = std::make_pair(&typeid(F), reinterpret_cast<void (Queue::*)()>(func));
Run Code Online (Sandbox Code Playgroud)

这假设F确实是一个指向成员函数的指针;如果用户尝试传递一些其他可调用对象,那么这将会中断。