Куда пропадает информация о типах аргументов в std::future? C++

Рейтинг: 1Ответов: 1Опубликовано: 22.02.2023

Набросал вот такой короткий пример.

void increment(int *i)
{
    ++(*i);
}

template<typename Func, typename ...Args>
auto bar(Func &&task, Args&& ...args)
{
    return std::async(std::launch::deferred, std::forward<Func>(task),
                      std::forward<Args>(args)...);
}

int main()
{
    int i = 1;
    auto f = bar(&increment, &i);
    f.wait();
    std::cout << i << std::endl;

    return 0;
}

Здесь в std::async толкается функция типа void(*int). При этом async возвращает std::future<void>. Но, получается, что если я в std::async толкну функция типа void(*int, *char), то всё равно мне вернется std::future<void>.

Вопрос: куда девается информация об аргументах? void(*int) и void(*int, *char) - это ведь разные типы, почему они оба могут храниться в std::future<void>?

P.S. : void(*int) и void(*int, *char) - разные типы. В таком случае как они могут храниться в одном типе std::future<void>? Как это может работать? Если внутри std::future лежит указатель на функцию типа void(*int), то void(*int, *char) туда уже не положишь. Но оно кладется. Почему?

Ответы

▲ 4

Если внутри std::future лежит указатель на функцию

А он там не лежит. Там лежит только указатель на память в куче, куда будет положено возвращаемое значение.

Вот вам самодельный игрушечный async(). Специально написанный плохо, без forward и прочего.

#include <future>
#include <iostream>
#include <thread>
#include <type_traits>

template <typename F, typename ...P>
auto my_async(F func, P ...params)
{
    using R = decltype(func(params...));
    std::promise<R> p;
    std::future<R> f = p.get_future();
    std::thread t([p = std::move(p), func, params...]() mutable
    {
        p.set_value(func(params...));
    });
    t.detach();
    return f;
}


int main()
{
    auto x = my_async([](int a, int b)
    {
        return a + b;
    }, 10, 20);
    std::cout << x.get() << '\n'; // 30
}