通过通用类型替换模板函数指针 [英] Replacing templated function pointer by generic type

查看:118
本文介绍了通过通用类型替换模板函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为 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> 模板。

It allows me to add bound function expressions to a queue and pop them afterwards (queue->push<int>(&Object::jumpAround, 10); and queue->pop()). The problem is, I could not find a generic object- and function-pointer that enabled me to implement this without the <class T> template.

我知道使用模板可能是最安全和最好的方法,但由于设计的代码实现这个队列,我需要摆脱它。任何想法?

I know that using templates would probably be the safest and best approach here but due to the design of the code implementing this queue I need to get rid of it. Any ideas?

我想这一定是可能的,因为 std :: bind 的第一个参数可以是任何函数,第二个可以是任何对象。

I guess it must be possible somehow because std::bind's first parameter can be any function and the second one can be any Object.

推荐答案

如果我理解,下面是你需要的:

If I understand, below is what you require:

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


b $ b

或者,更好的是,更改函数签名,并允许用户将 std :: function !这是正常的方式(参见例如 boost :: asio :: io_service :: post 。)

Or, even better, change your function signature and allow users to enqueue a std::function! This is the "normal" way (see for example, boost::asio::io_service::post.)

编辑:这是一个简单的例子:

Here is a simple example:

// Let the compiler do all the hard work for you..
template<typename T>
void enqueue(T f)
{
  queue.push(f);
}

现在可以将任何函数发布到此队列...

Now to post any function to this queue...

// Here you are posting the functor itself...
q.enqueue(std::bind(&bar::foo, &b, 15, 12));

这篇关于通过通用类型替换模板函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆