1

I have this code.

   int TA11::AsyncRunP(Unit *unit,Function func)
    {
        return 0;
    }
    int TA11::AsyncRunR(Unit& unit, Function func)
    {
        return 0;
    }
    
    void TA11::RunFunc(Unit& unit, Function func)
    {
        assert(!unit.fut_.valid());
    
        unit.fut_ = std::async(std::launch::async, &TA11::AsyncRunR, this, unit, func);
        unit.fut_ = std::async(std::launch::async, &TA11::AsyncRunP, this, &unit, func);
    }

VS2019 c++17 mode. (Function is a class enum)

the first std::async wont compile, second one is fine.

1>C:\work\pdp\mysim\mysim\Ta11Cassette.cpp(115,19): error C2672: 'std::async': no matching overloaded function found 1>C:\work\pdp\mysim\mysim\Ta11Cassette.cpp(115,79): error C2893: Failed to specialize function template 'std::future<_Invoke_traits<void,decay<_Ty>::type,decay<_ArgTypes>::type...>::type> std::async(std::launch,_Fty &&,_ArgTypes &&...)' 1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\future(1481): message : see declaration of 'std::async' 1>C:\work\pdp\mysim\mysim\Ta11Cassette.cpp(115,79): message : With the following template arguments: 1>C:\work\pdp\mysim\mysim\Ta11Cassette.cpp(115,79): message : '_Fty=int (__thiscall TA11::* )(TA11::Unit &,TA11::Function)' 1>C:\work\pdp\mysim\mysim\Ta11Cassette.cpp(115,79): message : '_ArgTypes={TA11 *, TA11::Unit &, TA11::Function &}'

pm100
  • 48,078
  • 23
  • 82
  • 145
  • 1
    `std::async` accepts `rvalues` only. You can use `std::ref()` to pass your var by reference. – asmmo Jun 24 '20 at 20:55

1 Answers1

1

std::async passes the arguments to the callable by value (doesn't make perfect forwarding), hence you got the error because your callable only accepts reference.

You can use std::ref() to pass your var by reference.

asmmo
  • 6,922
  • 1
  • 11
  • 25
  • I would say that the problem is not in `async` itself, the problem is in `AsyncRunR`. `async` accepts anything (via `_ArgTypes&&`), but it internally determines the result type of `AsyncRunR` (`_Invoke_traits<...>`), trying to invoke it with an rvalue (after `decay<...>`). But rvalue cannot bind to non-const lvalue reference, so `_Invoke_traits<...>` fails. – Evg Jun 24 '20 at 21:25
  • jeez, I though I understood rvalue : a thing that can occur on the right of an = sign. Cleary I dont cos for sure I can put the unit arg on the right side of an =. Any suggested reading? – pm100 Jun 24 '20 at 21:28
  • 2
    @pm100, you can put an lvalue on the right side, too. I like [this](https://stroustrup.com/terminology.pdf) explanation by Bjarne. – Evg Jun 24 '20 at 21:31
  • 1
    @Evg Yes, this is the error exactly. I'll update the answer. – asmmo Jun 24 '20 at 21:33
  • @Evg - thanks for the link, next coffee break – pm100 Jun 24 '20 at 21:51