2013-03-15 96 views
13

我刚刚开始使用C++ 11线程,我一直在努力(可能很愚蠢)的错误。 这是我的示例程序:C++ 11线程初始化与成员函数编译错误

#include <iostream> 
#include <thread> 
#include <future> 
using namespace std; 

class A { 
public: 
    A() { 
    cout << "A constructor\n"; 
    } 

    void foo() { 
    cout << "I'm foo() and I greet you.\n"; 
    } 

    static void foo2() { 
    cout << "I'm foo2() and I am static!\n"; 
    } 

    void operator()() { 
    cout << "I'm the operator(). Hi there!\n"; 
    } 
}; 

void hello1() { 
    cout << "Hello from outside class A\n"; 
} 

int main() { 
    A obj; 
    thread t1(hello1); // it works 
    thread t2(A::foo2); // it works 
    thread t3(obj.foo); // error 
    thread t4(obj);  // it works 

    t1.join(); 
    t2.join(); 
    t3.join(); 
    t4.join(); 
    return 0; 
} 

是否有可能从一个纯粹的成员函数启动一个线程?如果不是,我怎么能包装我的foo函数从对象obj能够创建这样的线程? 在此先感谢!

这是编译错误:

thread_test.cpp: In function ‘int main()’: thread_test.cpp:32:22: error: no matching function for call to ‘std::thread::thread()’

thread_test.cpp:32:22: note: candidates are:

/usr/include/c++/4.6/thread:133:7: note: std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (A::*)(), _Args = {}]

/usr/include/c++/4.6/thread:133:7: note: no known conversion for argument 1 from ‘’ to ‘void (A::*&&)()’

/usr/include/c++/4.6/thread:128:5: note: std::thread::thread(std::thread&&)

/usr/include/c++/4.6/thread:128:5: note: no known conversion for argument 1 from ‘’ to ‘std::thread&&’

/usr/include/c++/4.6/thread:124:5: note: std::thread::thread()

/usr/include/c++/4.6/thread:124:5: note: candidate expects 0 arguments, 1 provided

+3

尝试一个简单的lambda:'[&](){obj.foo();}'。 [Full code here](http://liveworkspace.org/code/4Fh1lL$1)。 – BoBTFish 2013-03-15 14:10:56

+0

谢谢Angew,我一定会在将来的帖子中改变标签。 – Rob013 2013-03-15 14:30:26

回答

20

你需要调用对象采取任何参数,因此

thread t3(&A::foo, &obj); 

应该做的伎俩。这具有创建可调用实体的效果,其在obj上调用A::foo

原因是A的非静态成员函数采用类型的隐式第一个参数(可能是cv限定的)A*。当您致电obj.foo()时,您实际上呼叫A::foo(&obj)。一旦你知道了,上面的咒语是非常有道理的。

+0

完美的谢谢!我很抱歉转贴了一个现有问题,我可能错过了正确的标签。顺便说一句,现在它的作品! – Rob013 2013-03-15 14:29:06

+2

@ Rob013很高兴帮助。其实,我刚刚意识到这在复制中没有很好的解释。 – juanchopanza 2013-03-15 14:42:41

+0

@juanchopanza我明白任何成员函数(非静态)都会采用该类型的隐式第一个参数(该实例的此指针)。但是,如果我将对象作为参数传递(就像你在线程中分配它的方式)来调用任何普通成员函数(例如A :: foo(&obj);)),为什么它不起作用?请告诉我更多关于这个的信息。这个概念的任何链接将会很好。谢谢.. – 2016-04-12 09:06:51