2013-02-16 64 views
5

Hãy xem xét các lớp sau đây:gọi std :: async chức năng thành viên

class Foo 
{ 
    private: 
     void bar(const size_t); 
    public: 
     void foo(); 
}; 

tại Foo::foo() nên bắt đầu bài thi bar, vì vậy đây là cách nó được thực hiện:

void Foo:foo() 
{ 
    auto handle = std::async(std::launch::async, &Foo::bar, this, 0); 
    handle.get(); 
} 

này hoạt động hoàn hảo với g ++ -4.6.3, nhưng không phải với g ++ - 4.5.2, thông báo lỗi là

include/c++/4.5.2/functional:180:9: Error: must use ».« or »->« to call pointer-to-member function in »std::declval with _Tp = void (Foo::*)(long unsigned int), typename std::add_rvalue_reference<_Tp>::type = void (Foo::&&)(long unsigned int) (...)«, e.g. »(... -> std::declval with _Tp = void (Foo::*)(long unsigned int), typename std::add_rvalue_reference<_Tp>::type = void (Foo::*&&)(long unsigned int)) (...)«

Vì vậy, rõ ràng là lỗi nằm trong phiên bản cũ của g ++. Có thể khắc phục sự cố này bằng cách đặt phương thức công khai và giới thiệu chức năng trợ giúp sau:

void barHelp(Foo* foo, const size_t n) 
{ 
    foo->bar(n); 
} 
void Foo:foo() 
{ 
    auto handle = std::async(std::launch::async, barHelp, this, 0); 
    handle.get(); 
} 

Tuy nhiên, đưa ra phương pháp công khai không phải là quyết định thiết kế tốt nhất. Có cách nào khác để giải quyết vấn đề này mà không cần thay đổi trình biên dịch và để phương thức riêng tư không?

Trả lời

9

Sự cố có vẻ là nó sẽ không phát huy hiệu quả với các chức năng của thành viên. Có lẽ bạn có thể std::bind chức năng thành viên để đối tượng của bạn đầu tiên, trước khi đi qua nó để std::async:

auto func = std::bind(&Foo::bar, this, std::placeholders::_1); 
auto handle = std::async(std::launch::async, func, 0); 
+0

Hoạt động tốt, cảm ơn bạn! – stefan

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