2013-03-15 48 views
13

Tôi chỉ mới bắt đầu sử dụng các chuỗi C++ 11 và tôi đã vật lộn với một lỗi (có thể là ngớ ngẩn). Đây là chương trình mẫu của tôi:C++ 11 Khởi tạo chủ đề với các hàm thành viên biên dịch lỗi

#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; 
} 

Có thể bắt đầu chuỗi từ chức năng thành viên thuần túy không? Nếu không, làm thế nào tôi có thể bọc hàm foo của mình từ đối tượng obj để có thể tạo chuỗi như vậy? Cảm ơn bạn trước!

Đây là lỗi biên dịch:

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

Hãy thử một lambda đơn giản: '[&]() {obj.foo();}'. [Full code here] (http://liveworkspace.org/code/4Fh1lL$1). – BoBTFish

+0

+1: Ví dụ mã nhỏ nhưng đầy đủ và thông báo lỗi không được rút gọn. Chỉ cần lưu ý rằng đoạn mã định dạng ở đây trên SO không thích các tab (Tôi đã sửa lỗi này cho bạn trong bài đăng này). – Angew

+0

Cảm ơn Angew, tôi chắc chắn sẽ thay đổi các tab trong các bài viết sau này. – Rob013

Trả lời

20

Bạn cần một đối tượng có thể được gọi tham gia không có tham số, vì vậy

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

nên làm các trick. Điều này có tác dụng tạo ra một thực thể có thể gọi được gọi là A::foo trên obj.

Lý do là chức năng thành viên không tĩnh của A có tham số đầu tiên tiềm ẩn của loại (có thể là đủ điều kiện cv) A*. Khi bạn gọi obj.foo(), bạn đang thực hiện một cách hiệu quả là A::foo(&obj). Một khi bạn biết điều đó, câu thần chú trên làm cho cảm giác hoàn hảo.

+0

Cảm ơn bạn! Tôi xin lỗi vì đã đăng lại câu hỏi hiện tại, tôi có thể bỏ lỡ các thẻ phù hợp. Btw, bây giờ nó hoạt động! – Rob013

+2

@ Rob013 Vui vì nó đã giúp. Trên thực tế, tôi chỉ nhận ra điều này không được giải thích rất rõ trong bản sao. – juanchopanza

+0

@juanchopanza tôi hiểu điểm rằng bất kỳ chức năng thành viên (không tĩnh) sẽ có tham số đầu tiên tiềm ẩn của loại đó (con trỏ của trường hợp đó). Nhưng tại sao nó không hoạt động nếu tôi vượt qua đối tượng như một đối số (cách bạn đã làm cho việc gán chúng vào chủ đề) để gọi bất kỳ chức năng thành viên bình thường (ví dụ: A :: foo (&obj);) Xin vui lòng cho tôi biết thêm về điều này .. bất kỳ liên kết cho khái niệm này sẽ làm tốt. Cảm ơn .. –

Các vấn đề liên quan