#include <iostream>
#include <functional>
#include <future>
#include <tchar.h>
void StartBackground(std::function<void()> notify)
{
    auto background = std::async([&]
    {
        notify(); // (A)
    });
}
int _tmain(int argc, _TCHAR* argv[])
{
    StartBackground([](){});
    char c; std::cin >> c;  // (B)
    while (1);
    return 0;
}
1) Build and run the code above using Visual Studio 2012.
2) Line (A) triggers an Access Violation in _VARIADIC_EXPAND_P1_0(_CLASS_FUNC_CLASS_0, , , , ):
First-chance exception at 0x0F96271E (msvcp110d.dll) in ConsoleApplication1.exe: 0xC0000005: Access violation writing location 0x0F9626D8
Most confusingly, the exception can be avoided by removing line (B).
Questions
- Why does the callable object notifyapparently conflict with the use ofstd::cin?
- What's wrong with this code?
The real world scenario for this simplified example is a function that executes some code in parallel and have that code call a user-supplied notify function when done.
Edit
I found at least one problem im my code: The background variable is destroyed as soon as StartBackground() exits. Since std::async may or may not start a separate thread, and std::thread calls terminate() if the thread is still joinable, this might be causing the problem.
The following variant works because it gives the task enough time to complete:
void StartBackground(std::function<void()> notify)
{
    auto background = std::async([&]
    {
        notify(); // (A)
    });
    std::this_thread::sleep_for(std::chrono::seconds(1));
}
Keeping the std::future object alive over a longer period instead of sleeping should also work. But the following code also causes the same access violation:
std::future<void> background;
void StartBackground(std::function<void()> notify)
{
    background = std::async([&]
    {
        notify(); // (A)
    });
}
whereas using a std::thread in the same manner works as expected:
std::thread background;
void StartBackground(std::function<void()> notify)
{
    background = std::thread([&]
    {
        notify(); // (A)
    });
}
I'm completely puzzled.
I must be missing some very crucial points here regarding std::async and std::thread.
 
    