将成员函数作为参数传递时,std :: thread构造函数调用不编译

时间:2019-09-30 18:50:09

标签: c++ multithreading c++17

为什么以下代码无法使用C ++ 17和Qt 5.9.5编译?

interpolator.h:

#ifndef INTERPOLATOR_H
#define INTERPOLATOR_H

#include <QVector2D>
#include <QVector3D>

#include <vector>

class Interpolator {

public:    
    void lerpTerrain(const QVector2D& p, std::vector<QVector3D>& points) const;

private:
    void lerpTerrainThread(std::vector<QVector3D>& points, size_t start, size_t end) const;
};

#endif // INTERPOLATOR_H

interpolator.cpp:

#include "interpolator.h"

#include <QDebug>

#include <thread>
#include <mutex>

void Interpolator::lerpTerrainThread(std::vector<QVector3D> &points, size_t start, size_t end) const {
    // ...
    qDebug() << "Function called by thread";
}

void Interpolator::lerpTerrain(const QVector2D& p, std::vector<QVector3D>& points) const {

    size_t numThreads = 3;
    std::vector<std::thread> threads(numThreads);

    size_t threadSpread = points.size() / numThreads;
    for (unsigned int i = 0; i < numThreads; i++) {
        size_t start = i * threadSpread;
        size_t end = (i + 1) * threadSpread + 1;

        // THE FOLLOWING LINE DOES NOT COMPILE:
        std::thread(&Interpolator::lerpTerrainThread, this, points, start, end);

    }
    for (auto& thread : threads) {
        thread.join();
    }
}

我添加了this作为构造函数参数,请参见this post

据我所知,上述代码应该可以正常编译,因为它与std::thread的必需构造函数匹配:

template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );

我尝试了多种不同的创建线程的方式,例如创建std::thread(Interpolator::lerpTerrainThread, this, points, start, end);std::thread(&Interpolator::lerpTerrainThread, points, start, end);,并且尝试使用qmake重建项目(未成功)。

QtCreator显示的两个编译错误如下:

/usr/include/c++/7.4.0/thread:242: error: no matching member function for call to '_M_invoke'
        -> decltype(std::declval<_Invoker&>()._M_invoke(_Indices()))
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~

/usr/include/c++/7.4.0/thread:186: error: type 'std::thread::_Invoker<std::tuple<void (Interpolator::*)
(std::vector<QVector3D, std::allocator<QVector3D> > &, unsigned long, unsigned long) const,
const Interpolator *, std::vector<QVector3D, std::allocator<QVector3D>>, unsigned long,
unsigned long> >' does not provide a call operator
       _M_run() { _M_func(); }
       ^~~~~~~

以某种方式需要Interpolator类的调用运算符,这对我来说没有太大意义。

我希望有人能解决这个问题。

编辑: 按照注释中的建议使用std::ref(points)无效。它可以编译,但会导致一个std::system_error (invalid argument)。因此,我不认为这是Passing object by reference to std::thread in C++11的副本。也许我只是看不到明显的东西,但我仍然不知道为什么这不起作用。

修改2: 没关系,我使用std::ref使它起作用。不知道那里出了什么问题,谢谢您的帮助。

0 个答案:

没有答案