Генерация обещания из шаблона Callable

Я пытаюсь создать обещание из функции шаблона, которая принимает тип Callable. Но я не уверен, как это сделать. Я пытался с помощью std::invoke_result_t, но для этого нужны аргументы, чтобы узнать тип результата, чего я не буду знать при создании обещания.

Любой способ, которым я могу вывести тип возвращаемого значения? Я предполагаю, что это может быть невозможно в случае универсальной лямбды, но работает ли что-нибудь на неуниверсальных лямбда-случаях?

template <typename Callable, typename Promise>
class Job {

public:
Job(Callable&& c, Promise&& p)
: callable(std::move(c))
, promise(std::move(p))
{}

auto getFuture() {
return /* a std::shared_future */;
}

template<typename... Args>
void call(Args&&... args) {
promise.set_value(std::invoke(callable, args...));
}

private:
Callable callable;
Promise promise;
};

template<typename Callable>
decltype(auto) makeJob(Callable&& c) {
std::promise</* some type */> promise = /* something */;
return Job(std::forward<Callable>(c), std::move(promise));
}

int main() {
f1 = [](int arg){return arg;};
auto job = makeJob(std::move(f1));
auto future = job.getFuture();
job.call(1);
std::cout << future.get() << '\n';
}

4

Решение

Любой способ, которым я могу вывести тип возвращаемого значения? Я предполагаю, что это может быть невозможно в случае универсальной лямбды, но работает ли что-нибудь на неуниверсальных лямбда-случаях?

Вы пометили C ++ 17 так … std::function и гиды дедукции ваши друзья.

Вы можете определить тип возвращаемого значения вызываемого объекта, например

typename decltype(std::function{c})::result_type;

Так что ваши makeJob() функция может быть написана

template <typename Callable>
auto makeJob (Callable && c)
{
using retT = typename decltype(std::function{c})::result_type;

return Job{std::forward<Callable>(c), std::promise<retT>{}};
}

То же самое в Job учебный класс.

Очевидно, это работает, потому что f1

auto f1 = [](int arg){return arg;};

имеет тип возврата, который не зависит от аргументов; с общей лямбда

// ..........vvvv
auto f1 = [](auto arg){return arg;};

это решение больше не работает, и я не думаю, что вы можете написать что-то, чтобы получить возвращаемый тип, не зная тип аргумента.

Ниже приведен полный пример компиляции

#include <future>
#include <memory>
#include <iostream>
#include <functional>

template <typename C, typename P>
class Job
{
public:
using retT
= typename decltype(std::function{std::declval<C>()})::result_type;

Job (C && c, P && p) : callable{std::move(c)}, promise{std::move(p)}
{ }

auto getFuture ()
{ return std::shared_future<retT>{ promise.get_future() }; }

template <typename ... Args>
void call (Args && ... args)
{ promise.set_value(std::invoke(callable, args...)); }

private:
C callable;
P promise;
};

template <typename Callable>
auto makeJob (Callable && c)
{
using retT
= typename decltype(std::function{c})::result_type;

return Job{std::forward<Callable>(c), std::promise<retT>{}};
}

int main ()
{
auto f1 = [](int arg){return arg;};
auto job = makeJob(std::move(f1));
auto future = job.getFuture();

job.call(42);

std::cout << future.get() << '\n';
}
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]