C++ 如何正确扩展std::thread以包装生成的线程

C++ 如何正确扩展std::thread以包装生成的线程,c++,c++11,stdthread,C++,C++11,Stdthread,我试图创建一个简单的包装器,以便在std::thread的lew中创建线程时由我的应用程序使用。 使用此应用程序线程包装器的唯一目的是确保在每个生成的线程上一致地调用某些代码。我原以为这很简单,但std::thread构造函数和参数传递相当复杂,我在这里遇到了非常隐晦的构建错误 这是我尝试做的一个简单示例: #include <thread> class AppThread : public std::thread { template< class Function

我试图创建一个简单的包装器,以便在std::thread的lew中创建线程时由我的应用程序使用。 使用此应用程序线程包装器的唯一目的是确保在每个生成的线程上一致地调用某些代码。我原以为这很简单,但std::thread构造函数和参数传递相当复杂,我在这里遇到了非常隐晦的构建错误

这是我尝试做的一个简单示例:

#include <thread>

class AppThread : public std::thread
{
    template< class Function, class... Args > 
    static void wrap( Function&& f, Args&&... args )
    {
        //Some code
        f( std::forward<Args>( args )... );
    }

public:
    template< class Function, class... Args > 
    explicit AppThread( Function&& f, Args&&... args ) : std::thread( AppThread::wrap<Function,Args...>,
                                                                      std::forward<Function>( f ), std::forward<Args>( args )... )
    {}
};

void runA() {}
void runB( int x ) {}

main()
{
    AppThread thread1 = AppThread( runA );
    //AppThread thread2 = AppThread( runB, 5 );
}
#包括
类AppThread:public std::thread
{
模板<类函数,类…参数>
静态无效换行(函数和函数、参数和…参数)
{
//一些代码
f(标准:正向(参数)…);
}
公众:
模板<类函数,类…参数>
显式AppThread(函数&&f,参数&&…参数):std::thread(AppThread::wrap,
标准::转发(f),标准::转发(args)
{}
};
void runA(){}
void runB(int x){}
main()
{
AppThread thread1=AppThread(runA);
//AppThread thread2=AppThread(runB,5);
}
我希望能够在使用std:thread的任何地方插入AppThread,因此扩展和重写构造函数似乎是最好的方法。但是将这些参数传递给我的包装方法会导致这种级联错误(gcc 7.2)

thread_wrap.cpp中包含的文件中的
:1:0:
gcc-7.2.0/include/c++/7.2.0/thread:在“struct std::thread::u Invoker”的实例化中:
gcc-7.2.0/include/c++/7.2.0/thread:127:22:std::thread(_-Callable&&,_-Args&&…)中的必填项[with-u-Callable=void(&)(void(&));_-Args={void(&)(}]
thread_wrap.cpp:15:130:从'AppThread::AppThread(函数&&,参数&&…[with Function=void(&));参数={}]中需要
螺纹缠绕。cpp:24:41:此处需要
gcc-7.2.0/include/c++/7.2.0/thread:240:2:错误:调用“std::thread::_Invoker::_M_invoke(std::thread::_Invoker::_index)”时没有匹配的函数
运算符()()
^~~~~~~~
gcc-7.2.0/include/c++/7.2.0/thread:231:4:注:候选:模板decltype(std:u调用((_S_declval)(…))std::thread:_调用程序::_调用(std:Index_tuple)[带长无符号int…Ind={u Ind};tuple=std::tuple]
_M_invoke(_Index_tuple)
^~~~~~~~~
gcc-7.2.0/include/c++/7.2.0/thread:231:4:注意:模板参数推导/替换失败:
gcc-7.2.0/include/c++/7.2.0/thread:替换“模板decltype(std::_调用(_S_declval()))std::thread::_调用程序::_调用(std:_索引_元组)[带长无符号int…_Ind={0,1}]:
gcc-7.2.0/include/c++/7.2.0/thread:240:2:必须来自“struct std::thread::u Invoker”
gcc-7.2.0/include/c++/7.2.0/thread:127:22:std::thread(_-Callable&&,_-Args&&…)中的必填项[with-u-Callable=void(&)(void(&));_-Args={void(&)(}]
thread_wrap.cpp:15:130:从'AppThread::AppThread(函数&&,参数&&…[with Function=void(&));参数={}]中需要
螺纹缠绕。cpp:24:41:此处需要
gcc-7.2.0/include/c++/7.2.0/thread:233:29:错误:调用“\uu invoke(std::\uu tuple\u element\t,std:\uu tuple\u element\t)”时没有匹配的函数
->decltype(std::__invoke(_S_declval()…))
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
在gcc-7.2.0/include/c++/7.2.0/tuple:41:0中包含的文件中,
从gcc-7.2.0/include/c++/7.2.0/bits/unique_ptr.h:37,
从gcc-7.2.0/include/c++/7.2.0/memory:80,
从gcc-7.2.0/include/c++/7.2.0/thread:39,
从thread_wrap.cpp:1:
gcc-7.2.0/include/c++/7.2.0/bits/invoke.h:89:5:注:候选:模板constexpr typename std::uuuu invoke_result::type std::uuu invoke(_Callable&,_Args&&…)
__调用(_可调用&&&&&&&&&&&&…_参数)
^~~~~~~~
gcc-7.2.0/include/c++/7.2.0/bits/invoke.h:89:5:注意:模板参数推导/替换失败:
gcc-7.2.0/include/c++/7.2.0/bits/invoke.h:替换“模板constexpr typename std::_invoke_result::type std::_invoke(_Callable&,_Args&&&…[带_Callable=void(*)(void(&));_Args={void(*)()()]):
gcc-7.2.0/include/c++/7.2.0/thread:233:29:替换“模板decltype(std::__调用(_S_declval()))std::thread::_调用程序::_调用(std:_索引_元组)[带长无符号int…_Ind={0,1}]时所需
gcc-7.2.0/include/c++/7.2.0/thread:240:2:必须来自“struct std::thread::u Invoker”
gcc-7.2.0/include/c++/7.2.0/thread:127:22:std::thread(_-Callable&&,_-Args&&…)中的必填项[with-u-Callable=void(&)(void(&));_-Args={void(&)(}]
thread_wrap.cpp:15:130:从'AppThread::AppThread(函数&&,参数&&…[with Function=void(&));参数={}]中需要
螺纹缠绕。cpp:24:41:此处需要
gcc-7.2.0/include/c++/7.2.0/bits/invoke.h:89:5:错误:在“struct std::\u invoke\u result”中没有名为“type”的类型
这里绝对需要一些洞察力!
谢谢

这是一个我认为萨姆的意图的例子。正如您所看到的,它只有几行代码,所以我就到此为止

#include <iostream>
#include <thread>
#include <functional>

void preamble (void) { std::cout << "preamble\n"; }

template <class F, class ... Args> std::thread ThreadWrapper (F f, Args&& ... args)
{
    return std::thread ([f, args...] () { preamble (); f (std::forward <Args...> (args...)); });
};

int main()
{
    std::thread t = ThreadWrapper ([] (std::string s) { std::cout << s << "\n"; }, "42");
    t.join ();
}

下面是一个我认为萨姆的意图的例子。正如您所看到的,它只有几行代码,所以我就到此为止

#include <iostream>
#include <thread>
#include <functional>

void preamble (void) { std::cout << "preamble\n"; }

template <class F, class ... Args> std::thread ThreadWrapper (F f, Args&& ... args)
{
    return std::thread ([f, args...] () { preamble (); f (std::forward <Args...> (args...)); });
};

int main()
{
    std::thread t = ThreadWrapper ([] (std::string s) { std::cout << s << "\n"; }, "42");
    t.join ();
}

我今早醒来时就明白了:) 由于std::thread会衰减它传递给函数的所有参数,所以当它调用我的wrap方法时,这些参数就是衰减的类型。但是,当我将模板参数传递给wrap时,它会得到未定义的类型:

std::thread( AppThread::wrap<Function,Args...>,  
std::thread(AppThread::wrap,
解决方案很简单,在实例化模板包装方法之前,我需要衰减类型:

std::thread( AppThread::wrap<std::decay_t<Function>,std::decay_t<Args>...>,  
std::thread(AppThread::wrap,

我今早醒来时就明白了:) 由于std::thread会衰减它传递给函数的所有参数,所以当它调用我的wrap方法时,这些参数就是衰减的类型
std::thread( AppThread::wrap<std::decay_t<Function>,std::decay_t<Args>...>,