c++ - std::thread() 和 std::ref() 在类内部使用时导致构建错误

标签 c++ multithreading c++11

我昨天发布了一个问题,但我没有可运行的示例来提供给其他用户。我现在这样做了,所以我删除了我的旧帖子。

当我尝试制作和使用 std::threads() 时,我有一些代码无法构建和 std::ref()在一个类(class)里面。我不明白生成的错误消息,它们都以 error: no matching function for call 行开头或 error: no type named ‘type’ .

我正在使用 Clion 和 CMake,以防万一。我的文件结构是:

Personal
--include
----main.h
--src
----main.cpp
----CMakeLists.txt
--CMakeLists.txt

CMakeLists.txt

# CMAKE version requirement
cmake_minimum_required(VERSION 3.12)

# Project name
project(scrap CXX)

# Configure the build
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE Debug)
add_compile_options(-W -Wall -ggdb)
include_directories(include)
include_directories(${CMAKE_SOURCE_DIR}/include)

# What is being built
add_executable(scrap)
add_subdirectory(src)

# Add external dependencies
find_package(Threads REQUIRED)
target_link_libraries(scrap ${CMAKE_THREAD_LIBS_INIT})

src/CMakeLists.txt

# Add targets
target_sources(scrap PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
        )

ma​​in.h

#ifndef PERSONAL_MAIN_H
#define PERSONAL_MAIN_H

#include <future>
#include <iostream>
#include <unistd.h>

class ScrapPaper
{
public:
    ScrapPaper();
    static void SpinUpThreads();
    void ThreadFunction1(std::promise<bool> &prom);
    void ThreadFunction2(std::promise<bool> &prom);

private:

};

#endif //PERSONAL_MAIN_H

main.cpp

#include "../include/main.h"

using namespace std;

void ScrapPaper::ThreadFunction1(promise<bool> &prom)
{
    cout << "Thread " << this_thread::get_id() << " working in ThreadFunction1!" << endl;
    sleep(10);

    cout << "Thread " << this_thread::get_id() << " finished sleeping in Function1" << endl;
    prom.set_value_at_thread_exit(true);
}

void ScrapPaper::ThreadFunction2(promise<bool> &prom)
{
    cout << "Thread " << this_thread::get_id() << " working in ThreadFunction2!" << endl;
    sleep(2);
    cout << "Thread " << this_thread::get_id() << " finished sleeping in Function2" << endl;
    prom.set_value_at_thread_exit(true);
}

void ScrapPaper::SpinUpThreads()
{
    promise<bool> promise1;
    future<bool> future1 = promise1.get_future();
    std::thread (&ScrapPaper::ThreadFunction1, ref(promise1)).detach();

    promise<bool> promise2;
    future<bool> future2 = promise2.get_future();
    std::thread (&ScrapPaper::ThreadFunction2, ref(promise2)).detach();

    if (future1.get() && future2.get())
    {
        cout << "Everything was a-okay" << endl;
    }
    else
    {
        cout << "Whoops, there was an error..." << endl;
    }
}

int main(int argc, char *argv[])
{
    cout << "In Main..." << endl;
    ScrapPaper::SpinUpThreads();

} // end main

我遇到的一些错误是:

error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (ScrapPaper::*)(std::promise<bool>&), std::reference_wrapper<std::promise<bool> > > >::_M_invoke(std::thread::_Invoker<std::tuple<void (ScrapPaper::*)(std::promise<bool>&), std::reference_wrapper<std::promise<bool> > > >::_Indices)’
  operator()()
  ^~~~~~~~

error: no type named ‘type’ in ‘struct std::__invoke_result<void (ScrapPaper::*)(std::promise<bool>&), std::reference_wrapper<std::promise<bool> > >’

当类(class)被带走时,只有一个 main()ThreadFunction1(...)ThreadFunction2(...) ,代码构建并运行。我有范围问题吗?非常感谢任何建议或帮助!

最佳答案

这里的问题是,由于您正在使用成员函数,因此您需要一个类的实例来调用成员函数。如果 SpinUpThreads 不是静态的,您可以使用

std::thread (&ScrapPaper::ThreadFunction1, this, ref(promise1)).detach();
std::thread (&ScrapPaper::ThreadFunction2, this, ref(promise2)).detach();

但由于它是静态的,因此您必须创建该类的实例以传递给线程的构造函数。您可以为两个调用共享一个对象,或者为每个线程提供它自己的对象。看起来像

ScrapPaper common;
std::thread (&ScrapPaper::ThreadFunction1, common, ref(promise1)).detach();
std::thread (&ScrapPaper::ThreadFunction2, common, ref(promise2)).detach();

//or

std::thread (&ScrapPaper::ThreadFunction1, ScrapPaper{}, ref(promise1)).detach();
std::thread (&ScrapPaper::ThreadFunction2, ScrapPaper{}, ref(promise2)).detach();

您还可以使用 lambda 来简化调用语法。如果您使用 lambda,您可以以更自然的方式编写函数调用,它看起来像

ScrapPaper common;
std::thread ([&](){ common.ThreadFunction1(promise1); }).detach();
std::thread ([&](){ common.ThreadFunction2(promise2); }).detach();

//or

std::thread ([&](){ ScrapPaper{}.ThreadFunction1(promise1); }).detach();
std::thread ([&](){ ScrapPaper{}.ThreadFunction2(promise2); }).detach();

关于c++ - std::thread() 和 std::ref() 在类内部使用时导致构建错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54830683/

相关文章:

c# - 现在是在 ASP.NET MVC 中使用多线程的好时机吗?它是如何实现的?

c++ - std::unique_ptr 的 "No-throw dereferencing"

python - 如何使用 boost.python 跨模块使用类?

c++ - 指针运算 : how are these statements different?

java - 这怎么可能,3 个线程处于阻塞状态等待同一个监视器,并且没有线程拥有该监视器

c++ - 如果我不使用变量,我可以在翻译单元中有多个定义吗?

c++ - 使用 std::string 在 DLL 中创建类。 C4251 警告

c++ - 在另一个 cpp 文件中使用枚举时出现问题

c++ - 给出编译错误的 const 对象的 vector

Java 执行器服务 : should I put a lock before to use execute?