简体   繁体   English

尝试使用std :: thread时发生编译器错误

[英]Compiler error when trying using std::thread

I ran into a compiler error when I tried to execute a function using std::thread. 尝试使用std :: thread执行函数时遇到编译器错误。 The error says : "error C2672: 'std::invoke': no matching overloaded function found". 该错误说:“错误C2672:'std :: invoke':找不到匹配的重载函数”。

Here is a code snippet: 这是一个代码片段:

void GetMinMax_X(const std::vector<Vertex>& iAllVertices, double & oMin_X, 
double & oMax_X)
{
    auto MinMax_X = std::minmax_element(iAllVertices.begin(), 
iAllVertices.end(), [](const Vertex& i, const Vertex& j)
    {
        return i.GetX() < j.GetX();
    });
    oMin_X = MinMax_X.first->GetX();
    oMax_X = MinMax_X.second->GetX();
}

int main()
{
    std::vector<Vertex>;
    // Some functions to fill the Vertex vector......

    double Min_X = 0;
    double Max_X = 0;
    std::thread first (GetMinMax_X, AllVertices, Min_X, Max_X);
    first.join();

    return 0;
}

Thanks! 谢谢!

The error comes up because std::thread uses std::invoke behind the scenes to invoke GetMinMax_X , but with the arguments copied/moved. 由于std::thread在后台使用std::invoke调用GetMinMax_X ,但复制/移动了参数,因此出现错误。 In particular, you cannot use 特别是,您不能使用

void GetMinMax_X(const std::vector<int>& iAllVertices, double & oMin_X, double & oMax_X)

because you would be forming references to the copies, which is not what you want. 因为您将形成对副本的引用,但这不是您想要的。

You could still use 仍然可以使用

void GetMinMax_X(const std::vector<int>& iAllVertices, const double & oMin_X, const double & oMax_X)

but that would not help you get back the values into the main thread. 但这并不能帮助您将值返回到主线程中。

The solution is to use std::ref : 解决方案是使用std::ref

std::thread first(GetMinMax_X, AllVertices, std::ref(Min_X), std::ref(Max_X));

https://godbolt.org/z/ClK3Cb https://godbolt.org/z/ClK3Cb

See also what cppreference has to say about std::thread (where this "limitation" and the workaround are described): 另请参阅关于std::thread cppreference怎么说(描述了此“限制”和解决方法):

https://en.cppreference.com/w/cpp/thread/thread/thread https://en.cppreference.com/w/cpp/thread/thread/thread

The arguments to the thread function are moved or copied by value. 线程函数的参数按值移动或复制。 If a reference argument needs to be passed to the thread function, it has to be wrapped (eg with std::ref or std::cref). 如果需要将引用参数传递给线程函数,则必须将其包装(例如,使用std :: ref或std :: cref)。

Any return value from the function is ignored. 该函数的所有返回值都将被忽略。 If the function throws an exception, std::terminate is called. 如果函数抛出异常,则调用std :: terminate。 In order to pass return values or exceptions back to the calling thread, std::promise or std::async may be used. 为了将返回值或异常传递回调用线程,可以使用std :: promise或std :: async。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM