成员函数的std :: async调用

时间:2013-02-16 16:46:43

标签: c++ class asynchronous c++11 function-pointers

考虑以下课程:

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:错误:必须使用»。«或» - > «在»std ::中调用指向成员的函数declval with _Tp = void(Foo :: *)(long unsigned int),typename 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();
}

但是,公开方法并不是最好的设计决策。有没有其他方法可以解决这个问题没有更改编译器并将方法保密:

2 个答案:

答案 0 :(得分:11)

问题似乎是它对成员函数不起作用。在将对象传递给std::bind之前,您可以首先std::async成员对您的对象起作用:

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

答案 1 :(得分:0)

相对于std :: bind,我更喜欢lambdas

   public void clickBelangrijkeNotitie() {
       wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(Constant.BELANGRIJKE_NOTITIE_ACTIVITY_CSS_LOCATOR_VALUE)));
       HandleNewWindow.setMainWindow(driver);
       elements.belangrijkeNotitie.click();
       HandleNewWindow.switchToNewWindow(driver, wait);
       System.out.println("switching to new window");
   }

public void typeNotitie(String notitie) {
  wait.until(ExpectedConditions.elementToBeClickable(By.id(Constant.NOTITIE_INPUT_FIELD_ID_LOCATOR_VALUE)));
       elements.notitie.clear();
       elements.notitie.sendKeys(notitie);
   }

   public void clickOkButton() {
       elements.okButton.click();
       HandleNewWindow.switchToMainWindow(driver);
   }

   public class HandleNewWindow {
    protected static String mainWindow;
    public static void setMainWindow(WebDriver driver) {
        mainWindow = driver.getWindowHandle();
    }

    public static void switchToNewWindow(WebDriver driver, WebDriverWait wait) {
        wait.until(ExpectedConditions.numberOfWindowsToBe(2));
        Set<String> allWindows = driver.getWindowHandles();
        for (String newWindow : allWindows) {
            if (!newWindow.equals(mainWindow)) {
                driver.switchTo().window(newWindow);
            }
        }
    }
    public static void switchToMainWindow(WebDriver driver) {
        driver.switchTo().window(mainWindow);
    }
}
     @Test (testName = "Create belangrijke and standaard notitie")
    public void testBelangrijkeEnStandaardNotitie() {
            logIn.logInToPowerCurveWithUserX(npa.USERNAME, npa.PASSWORD);
            search.searchAccount(accountNummer3);
            activities.clickNotitieParentActivity();
            activities.clickBelangrijkeNotitie();
            popUpActivities.typeNotitie("Een belangrijke notitie: Dit is een effectieve test....");
            popUpActivities.clickOkButton();
            activities.clickNotitieParentActivity();
            activities.clickStandaardNotitie();
            popUpActivities.typeNotitie("Standaard notitie ook maar even doen.......");
            popUpActivities.clickOkButton();
            toolbarActivities.clickAccountOntladenButton();
            logOut.logOutFromPowerCurve();
    }
}

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

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