2013-02-16 4 views
5

Рассмотрим следующий класс:станд :: асинхронной вызов функции члена

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

Теперь Foo::foo() должны начать темы, выполняющийся bar, так это то, как он реализован:

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

Это работает безотказно с г ++ -4.6.3, но не с g ++ - 4.5.2, сообщение об ошибке

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)) (...)«

Очевидно, что ошибка лежит в старой версии g ++. Можно обойти эту проблему, сделав метод общественности и вводя следующие вспомогательные функции:

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(); 
} 

Однако, делая публичный метод не является лучшим дизайнерским решением. Есть ли другой способ обойти эту проблему без, изменяя компилятор и оставляя метод приватным?

ответ

9

Проблема заключается в том, что она не будет хорошо играть с функциями-членами. Возможно, вы можете std::bind функцию члена к объекту первого, прежде чем передать его std::async:

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

работает отлично, спасибо! – stefan