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):
U
is not used in the parameter list ofentity
, thus it is not deduced during the template argument deduction. It tries to deduceCb
, butCb
depends onU
.The generated deduction guide from
entity
constructor has the same issue.R
cannot be deduced.