I want my class object's ctor to accept a functor that is able to be converted to a std::packaged_task<R()> whereas R is auto deduced from the functor's return value. Here's what I've got so far:
#include <utility>
#include <future>
#include <concepts>
#include <cstdio>
template <typename R>
struct entity
{
template <std::convertible_to<std::packaged_task<R>> Cb>
entity(Cb&& fn)
: fn_{ std::move(fn) }
{ }
std::packaged_task<R()> fn_;
};
template <typename U, std::convertible_to<std::packaged_task<U()>> Cb>
entity(Cb&& fn) -> entity<decltype(fn())>;
int main()
{
entity e([]{ return 10; });
}
Even though I'm providing a deduction guide, my naive approach doesn't work. I suspect it has to do with the deduction guide specifying std::convertible_to<std::packaged_task<U()>> concept where gcc is struggling to substitute U for any type, hence making the deduction guide worthless. Can this be augmented?
<source>:12:5: note: template argument deduction/substitution failed:
<source>:25:30: note: couldn't deduce template parameter 'R'
25 | entity e([]{ return 10; });
|
I managed to find a workaround. The idea is to first get the return type of the Callable, then check the return type by constraining the constructor.
The issue in your code snippet is (I believe):
Uis not used in the parameter list ofentity, thus it is not deduced during the template argument deduction. It tries to deduceCb, butCbdepends onU.The generated deduction guide from
entityconstructor has the same issue.Rcannot be deduced.