vendredi 22 février 2019

std::thread() and std::ref() cause build errors when used inside of a class

I posted a question yesterday but I didn't have a runnable example to give other users. I do now, so I deleted my old post.

I have some code that fails to build when I attempt to make and use std::threads() and std::ref() inside of a class. I do not understand the error messages that are produced, which all start with the line error: no matching function for call or error: no type named ‘type’.

I am using Clion and CMake, incase that matters. My file structure is:

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
        )

main.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

Some of the errors that I am getting are:

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()()
  ^~~~~~~~

and

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

When the class is taken away and there is just a main() and the ThreadFunction1(...) and ThreadFunction2(...), the code builds and runs. Am I having a scope problem? Any advice or help is greatly appreciated!

Aucun commentaire:

Enregistrer un commentaire