12

Consider the following class:

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

now Foo::foo() should start threads executing bar, so this is how it's implemented:

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

This works flawlessly with g++-4.6.3, but not with g++-4.5.2, the error message is

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

So obviously the error lies within the old version of g++. It is possible to work around this issue by making the method public and introducing the following helper function:

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

However, making a method public isn't the best design decision. Is there another way to work around this issue without changing the compiler and leaving the method private?

2 Answers 2

14

The problem appears to be that it won't play nice with member functions. Perhaps you can std::bind the member function to your object first, before passing it to std::async:

auto func = std::bind(&Foo::bar, this, std::placeholders::_1);
auto handle = std::async(std::launch::async, func, 0);
Sign up to request clarification or add additional context in comments.

Comments

5

I would prefer lambdas to 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;
}

or, but less readable to me,

        auto handle = std::async(std::launch::async, [this](const size_t num){
            this->bar(num);
        }, 0);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.