我目前正在编写一个与 co_await 一起使用的协程/promise 库,当有不相关的 lambda 返回任务类型时,我很难约束成员函数
coroutine_traits
。
在 Godbolt 上重现问题的示例:现在显然 TaskType 在这里还没有完全实现(它是在真实版本中)。问题是这个编译错误:.../type_traits:3514:60: error: incomplete type 'const (lambda at <source>:38:14)' used in type trait expression
3514 | inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived);
| ^
<source>:13:29: note: in instantiation of variable template specialization 'std::is_base_of_v<SomeSafeClassA, const (lambda at <source>:38:14)>' requested here
13 | concept IsSafeClassA = std::is_base_of_v<SomeSafeClassA, T>;
现在 lambda - 如果它是一个完整的类型 - 无论如何都会失败
is_base_of
测试。我想要的是 lambda 匹配第一个模板特化;这个:
template<typename... Args>
struct coroutine_traits<TaskType<int>, Args...>{
using promise_type = TaskType<int>;
};
不会因基于类的专业化的类型不完整而引发编译器错误。这些专门化适用于成员函数,与 lambda 完全无关,并且不应该被评估(或者至少被评估并且无法匹配,而不是导致编译错误)。如何定义基于类的 coroutine_traits
我现在所做的是添加 lambda 可以返回的任务类型的更具体的专业化,例如
template <typename ResultType> class TLambdaTask : public TTask<ResultType>
{
public:
// ... pass through any constructors down to TTask
};
然后我可以为这个特定于 lambda 的类型定义一个专门化:
template <typename ReturnType, typename... Args>
struct coroutine_traits<TLambdaTask<ReturnType>, Args...>
{
// using promise_type = ...
};
任何使用
co_await
的 lambda 都可以返回此特定于 lambda 的类型,该类型只能与 TLambdaTask
特化匹配(而不是一般
TTask
的类特化):
auto k = []() -> TLambdaTask<int> {
co_return 6;
};
不过,如果有人有办法在没有派生 TLambdaTask
类型的情况下完成这项工作,那就更理想了。