11

考虑以下类:

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

这适用于 g++-4.6.3,但不适用于 g++-4.5.2,错误消息是

include/c++/4.5.2/functional:180:9: 错误:必须使用 »。« 或 »-> « 以 _Tp = void (Foo::*)(long unsigned int), 类型名 std::add_rvalue_reference<_Tp>::type = void ( Foo:: &&)(long unsigned int) (...)«,例如 »(... -> 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();
}

然而,公开一个方法并不是最好的设计决策。是否有另一种方法可以解决此问题,而无需更改编译器并将方法保留为私有?

4

2 回答 2

13

问题似乎是它不能很好地与成员函数配合使用。也许您可以std::bind先将成员函数传递给您的对象,然后再将其传递给std::async

auto func = std::bind(&Foo::bar, this, std::placeholders::_1);
auto handle = std::async(std::launch::async, func, 0);
于 2013-02-16T16:49:59.733 回答
4

我更喜欢 lambdas 到 std::bind

#include <iostream>
#include <future>

class Foo
{
private:
    void bar(const size_t)
    {}
public:
    void foo()
    {
        auto handle = std::async(std::launch::async, [this](){
            this->bar(0);
        });
        handle.get();
    }
};

int main()
{
    Foo foo;
    foo.foo();
    return 0;
}

或者,但对我来说可读性较差,

        auto handle = std::async(std::launch::async, [this](const size_t num){
            this->bar(num);
        }, 0);
于 2019-07-10T14:52:21.880 回答