在演绎指南中约束输入类型



我希望我的类对象的函子接受一个能够转换为std::packaged_task<R()>的函子,而R是从函子的返回值自动推导出来的。以下是我目前得到的:

演示
#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; });
}

尽管我提供了一个演绎指南,但我天真的方法不起作用。我怀疑它与指定std::convertible_to<std::packaged_task<U()>>概念的演绎指南有关,其中gcc正在努力用U代替任何类型,因此使得演绎指南毫无价值。这个可以增强吗?

<source>:12:5: note:   template argument deduction/substitution failed:
<source>:25:30: note:   couldn't deduce template parameter 'R'
25 |     entity e([]{ return 10; });
|           

我设法找到了一个解决办法。其思想是首先获取Callable的返回类型,然后通过约束构造函数来检查返回类型。

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; });
}

你的代码片段中的问题是(我相信):

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

U不在entity的参数表中,因此在模板参数推导时不推导。它试图推断出Cb,但Cb依赖于U

entity构造函数生成的推导指南也有同样的问题。R不能被推断

最新更新