Qt如何在QtConcurrent中绑定指针到非静态成员函数

How does Qt bind pointers-to-non-static-member-functions in QtConcurrent?

本文关键字:指针 静态成员 函数 绑定 QtConcurrent Qt      更新时间:2023-10-16

来自QtConcurrent文档:

QByteArray bytearray = "hello world";
QFuture<QList<QByteArray> > future = QtConcurrent::run(bytearray, &QByteArray::split), ',');
...
QList<QByteArray> result = future.result();
上面的代码片段似乎以类似于std::tr1::bind (std::bind for> c++ 11)的方式绑定函数。也就是说,它接受一个非静态成员函数(QByteArray::split()),并(在稍后的某个时候)在它是成员的对象的特定实例(我们已经提供了bytearray)上调用它。

Qt是如何实现的?它是使用std::tr1::bindboost::bind在幕后某处?

文档也提到了使用std::tr1boost的情况,但我不完全理解绑定函数在该上下文中的含义。与使用tr1boost的其他情况相比,上述情况实际上不同/更专业/更简单吗?

我试图让我的方式通过源,但我很快就迷路了!

我将尝试自己回答,因为现有的答案(非常感谢@Mike Brown和@skyhisi)奠定了基础,但没有解决这个具体情况…

From source:

QtConcurrent:运行(…):

template <typename T, typename Class>
QFuture<T> run(const Class &object, T (Class::*fn)())
{
  return (new QT_TYPENAME SelectStoredMemberFunctionCall0<T, Class>::type(fn, object))->start();
}

SelectStoredMemberFunctionCall0 :

template <typename T, typename Class>
struct SelectStoredMemberFunctionCall0
{
  typedef typename SelectSpecialization<T>::template
    Type<StoredMemberFunctionCall0    <T, Class>,
      VoidStoredMemberFunctionCall0<T, Class> >::type type;
};

VoidStoredMemberFunctionCall0 :

template <typename T, typename Class>
class VoidStoredMemberFunctionCall0 : public RunFunctionTask<T>
{
public:
  VoidStoredMemberFunctionCall0(T (Class::*_fn)() , const Class &_object)
  : fn(_fn), object(_object){ }
  void runFunctor()
  {
    (object.*fn)();
  }
private:
  T (Class::*fn)();
  Class object;
};
考虑到上面的情况,我可以看到Qt以正常的方式存储指向成员函数的指针,但是通过在模板中修饰它,否则就不会被注意到,从而产生了泛型的错觉。

VoidStoredMemberFunctionCall0::object的类型和VoidStoredMemberFunctionCall0::fn的签名都在上面传递给QtConcurrent::run的参数中指定了。

老实说,我甚至不知道这种"隐式"模板化是可能的。有人能推荐进一步的阅读吗?

c++ FAQ很好地解释了指向成员函数的指针,并解释了其缺陷。

在某些地方会有这样一行:

ret_val = obj_ptr->*func_ptr(param);

但是它将被包装在模板中,以允许传递任何对象类型和参数类型,并且线程调度也将在那里混合。

传递了一个函数指针和一个声明函数的类的实例。调用它就像从对象中解引用函数指针一样简单。这个StackOverflow问题显示了答案