#Refrences as args to functions called using std::async

13 messages · Page 1 of 1 (latest)

broken gazelle
#

The other day, I was writing some code, and wanted to do something like this:

#include <future>
#include <iostream>

class AsyncTesting {
  public:
    void callAsyncFunction() {
      bool testingBool = false;
      std::future<bool> inversedBool = std::async(&AsyncTesting::inverseBoolAsync, this, testingBool);
      // do stuff with my bool (just print it for testing purposes)
      std::cout << inversedBool.get() << std::endl;
    }
    
    bool inverseBoolAsync(bool& arg) {
       return (!arg);
    }
    
};

int main() {
  AsyncTesting testObj;
  testObj.callAsyncFunction();
  return 0;
}

But upon compiling (g++), I get this string of errors:
https://pastebin.com/cmwy28FZ

I understand that having the same variable being overwritten at the same time could be problematic, but I'm guaranteed not to use the variable before I future.get() it. Is there any way to tell the compiler this, or is this code just inherently problematic & I just need to use pointers here (because they seem to work, just are not personally preferred)

P.S. Sorry if I formatted anything incorrectly or used wrong tags, I'm new here!

modern swanBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

uncut socket
winged steepleBOT
#
Critical error:

You are sending requests too fast!

uncut socket
#

;compile ```cpp
#include <future>
#include <iostream>

class AsyncTesting {
public:
void callAsyncFunction() {
bool testingBool = false;
std::future<bool> inversedBool = std::async(&AsyncTesting::inverseBoolAsync, this, std::ref(testingBool));
// do stuff with my bool (just print it for testing purposes)
std::cout << inversedBool.get() << std::endl;
}

bool inverseBoolAsync(bool& arg) {
   return (!arg);
}

};

int main() {
AsyncTesting testObj;
testObj.callAsyncFunction();
return 0;
}

winged steepleBOT
#
Program Output
1
harsh grove
#

for context, things like std::async pretty much have to copy the arguments that you're providing, but if the callable requires a mutable lvalue reference, it just doesn't make sense to give it a copy of the original

#

one workaround is to wrap the original object into a std::reference_wrapper, that's what std::ref does for you in a somewhat nice syntax
std::reference_wrapper is an object that basically wraps a pointer to the original object, and which can implicitly be converted into a reference to that original object

#

another common solution is to use lambda expressions instead

#

;compile

#include <future>
#include <iostream>

class AsyncTesting {
  public:
    void callAsyncFunction() {
      bool testingBool = false;
      std::future<bool> inversedBool = std::async([&]{ return inverseBoolAsync(testingBool); });
      // do stuff with my bool (just print it for testing purposes)
      std::cout << inversedBool.get() << std::endl;
    }
    
    bool inverseBoolAsync(bool& arg) {
       return (!arg);
    }
    
};

int main() {
  AsyncTesting testObj;
  testObj.callAsyncFunction();
  return 0;
}
winged steepleBOT
#
Program Output
1
broken gazelle
#

!solved