C++线程错误 - 使用类参数编译时错误

问题描述:

我找到了页面C++ thread error: no type named type,并在下面报告了类似的错误消息。尽我所知,该页面上的答案并不包括这种情况。无可否认,一定有一些简单的东西,我在这里毫无头绪。C++线程错误 - 使用类参数编译时错误

我一直在尝试在我正在使用的C++程序中使用线程。我有一个初始版本与boost::thread工作没有任何问题。今天早上,我试图重写我的代码,使用std::thread而不是boost::thread。那时我突然遇到了我不明白的编译时错误。我已将问题简化为以下代码片段。

结果?只要我尝试将自己的用户定义的类的引用作为函数参数传递,程序就无法编译。

#include <iostream> 
#include <thread> 

class TestClass { } ; 

void testfunc1 (void)   { std::cout << "Hello World TF1" << std::endl ; } 
void testfunc2 (double val)  { std::cout << "Hello World TF2" << std::endl ; } 
void testfunc3 (TestClass & tc) { std::cout << "Hello World TF3" << std::endl ; } 

int main (int argc, char *argv[]) 
{ 
    std::thread t1 (testfunc1) ; 

    double tv ; 
    std::thread t2 (testfunc2, tv) ; 

    TestClass tc ; 
    std::thread t3 (testfunc3, tc) ; // compiler generates error here 

    return 0 ; 
} 

只要我注释掉最后一行代码,代码就会被编译。但是,当它出现时,我会收到下面的编译时错误。

$ g++ -std=c++11 test.cpp 
In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/thread:39:0, 
       from test.cpp:3: 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/functional: In instantiation of ‘struct std::_Bind_simple<void (*(TestClass))(TestClass&)>’: 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/thread:142:59: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(TestClass&); _Args = {TestClass&}]’ 
test.cpp:19:33: required from here 
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/functional:1505:61: error: no type named ‘type’ in ‘class std::result_of<void (*(TestClass))(TestClass&)>’ 
     typedef typename result_of<_Callable(_Args...)>::type result_type; 
                  ^
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/functional:1526:9: error: no type named ‘type’ in ‘class std::result_of<void (*(TestClass))(TestClass&)>’ 
     _M_invoke(_Index_tuple<_Indices...>) 

显然有一些类型相关的问题,但我无法破译这个错误信息。任何想法是什么问题? (我碰巧使用Cygwin在Windows 10的机器上,但我不认为这个问题描述的是相关的。)

这因为std::thread不能存储C++引用,所以它与std::vector<T&>不能存在的相似。所以,为了传递参考,标准库中有一个reference wrapper。它基本上是一个指针,它模仿了一些语言引用的行为。 std::refstd::cref(用于const引用)函数用于创建std::reference_wrapper(它们是方便的函数,因为它们具有模板类型推演和较短的名称)的对象。

,你必须在你的代码中添加的唯一的事情是std::ref函数调用,就像这样:

TestClass tc; 
std::thread t3(testfunc3, std::ref(tc)); 
+0

谢谢!从来不会想到我自己。非常感激! –

要通过引用您需要使用std::ref包装:

std::thread t3 (testfunc3, std::ref (tc)) ; 
+0

谢谢!感谢帮助。 –