简体   繁体   中英

Constrain an input type in deduction guide

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:

Demo

#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.

template <typename R>
struct entity {
  template <class Cb> requires std::constructible_from<std::packaged_task<R()>, Cb &&>
  entity(Cb &&fn) : fn_(std::forward<Cb>(fn)) {}

  std::packaged_task<R()> fn_;
};

template <class Cb>
entity(Cb &&) -> entity<std::invoke_result_t<Cb &&>>;

int main()
{
  entity e([]{ return 10; });
}

The issue in your code snippet is (I believe):

template <typename U, std::convertible_to<std::packaged_task<U()>> Cb>
entity(Cb&& fn) -> entity<decltype(fn())>;

U is not used in the parameter list of entity , thus it is not deduced during the template argument deduction. It tries to deduce Cb , but Cb depends on U .

The generated deduction guide from entity constructor has the same issue. R cannot be deduced.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM