我继承了以下内容:
template <typename T>
concept IsAwaiter = requires {
typename T::await_ready;
typename T::await_suspend;
typename T::await_resume;
};
template <typename ...AWAITABLES>
concept IsAwaitables = typename std::conjunction<IsAwaiter<AWAITABLES>...>::type;
使用clang 10.0.0进行构建会导致以下错误:
IsAwaiter.h:43:50: error: template argument for template type parameter must be a type
也许只是一个简单的语法问题,但是我发现很难找到一个示例,该示例显示了如何基于可变模板概念参数创建概念。
任何帮助表示赞赏!
答案 0 :(得分:7)
std::conjunction
用于类型特征。 std::conjunction<IsAwaiter<AWAITABLES>...>
是具有成员static bool value = (IsAwaiter<AWAITABLES>::value && ...)
的类型,其中每个IsAwaiter<AWAITABLES>
本身都是具有自己的static bool
成员value
的类型特征。当IsAwaiter<AWAITABLES>
是一个概念时,这是荒谬的,因为概念不是类型特征。他们是“只是”布尔值。使用折叠表达式。
template <typename... AWAITABLES>
concept IsAwaitables = (IsAwaiter<AWAITABLES> && ...);
就是这样。
struct Dummy {
using await_ready = Dummy;
using await_suspend = Dummy;
using await_resume = Dummy;
};
int main() {
static_assert(IsAwaitables<>);
static_assert(IsAwaitables<Dummy>);
static_assert(IsAwaitables<Dummy, Dummy>);
}
答案 1 :(得分:5)
作为HTNW points out,您需要:
template <typename ...T>
concept IsAwaitables = (IsAwaiter<T> && ...);
但是,实际上,您是否甚至需要这个概念?您可以直接使用IsAwaiter
。大概应该将其命名为Awaiter
-概念的典型约定是将它们命名为名词而不是问题(例如Range
与IsRange
)。
如果要使用参数包,则还是要使用它:
template <Awaiter... T>
void f(T... awaiters);
与缩写功能模板语法相同:
void f(Awaiter auto... awaiters);
或者如果您有固定的数量,则这毫无意义:
template <Awaiter T, Awaiter U>
void f(T, U);
即使在不合适的其他情况下,最好还是手动使用Awaiter
和fold-expression。因此,我对连词概念的开头提出了疑问。