我为std::bind
和std::queue
撰写了以下包装:
#include "Queue.h"
template<class T>
Queue<T>::Queue(T* input)
{
instance = input;
}
template<class T> template<typename... Args>
int Queue<T>::push(int (T::*func)(Args... args), Args... args)
{
queue.push(std::bind(func, instance, args...));
return queue.size();
}
template<class T>
int Queue<T>::pop()
{
if(!queue.empty())
{
queue.front()();
queue.pop();
return queue.size();
}
return 0;
}
template<class T>
bool Queue<T>::empty()
{
return queue.empty();
}
template<class T>
size_t Queue<T>::size()
{
return queue.size();
}
带有以下标题:
#ifndef QUEUE_H_
#define QUEUE_H_
#include <functional>
#include <queue>
template <class T>
class Queue
{
private:
std::queue<std::function<void()>> queue; /**< the messaging queue, appended to using enqueue(), popped from using dequeue() */
T* instance;
public:
Queue(T*);
template<typename... Args>
int enqueue(int (T::*f)(Args... args), Args... args);
int dequeue();
bool empty();
size_t size();
};
#endif
它允许我将绑定的函数表达式添加到队列中,然后将它们弹出(queue->push<int>(&Object::jumpAround, 10);
和queue->pop()
)。问题是,我找不到一个通用的对象和函数指针,它使我能够在没有<class T>
模板的情况下实现它。
我知道使用模板可能是最安全和最好的方法,但由于设计实现此队列的代码,我需要摆脱它。有什么想法吗?
我想这肯定是可能的,因为std::bind
的第一个参数可以是任何函数,第二个参数可以是任何对象。
答案 0 :(得分:3)
如果我理解,以下是您的要求:
class Queue
{
private:
std::queue<std::function<void()>> queue; /**< the messaging queue, appended to using enqueue(), popped from using dequeue() */
public:
// pass in the instance of the object and simply allow the compiler to deduce the function pointer nastiness...
template<typename T, typename F, typename... Args>
void enqueue(T instance, F func, Args... args)
{
queue.push(std::bind(func, instance, args...));
}
int dequeue()
{
if(!queue.empty())
{
queue.front()();
queue.pop();
}
}
};
哦,以及如何使用它:
struct foo
{
void bar(int a)
{
std::cout << "foo::bar: " << a << std::endl;
}
};
struct bar
{
void foo(int a, int c)
{
std::cout << "bar::foo: " << (a + c)<< std::endl;
}
};
int main(void)
{
Queue q;
foo f;
bar b;
q.enqueue(&f, &foo::bar, 10);
q.enqueue(&b, &bar::foo, 10, 11);
q.dequeue();
q.dequeue();
}
应输出:
foo::bar: 10
bar::foo: 21
或者,更好的是,更改您的功能签名并允许用户将std::function
入队!这是“正常”方式(例如,参见boost::asio::io_service::post
。)
编辑:这是一个简单的例子:
// Let the compiler do all the hard work for you..
template<typename T>
void enqueue(T f)
{
queue.push(f);
}
现在将任何功能发布到此队列......
// Here you are posting the functor itself...
q.enqueue(std::bind(&bar::foo, &b, 15, 12));