我继承了以下内容:
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也许只是一个简单的语法问题,但我发现很难找到一个示例来说明如何基于可变模板概念参数创建概念。
感谢任何人的帮助!
发布于 2020-09-09 02:45:49
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>);
}发布于 2020-09-09 03:30:55
作为HTNW points out,您需要:
template <typename ...T>
concept IsAwaitables = (IsAwaiter<T> && ...);但说真的,你真的需要这个概念吗?您可以直接使用IsAwaiter。它可能只应该被命名为Awaiter --概念的典型约定是将它们命名为名词,而不是疑问句(例如,Range vs IsRange)。
如果你正在使用一个参数包,你无论如何都会想要使用它:
template <Awaiter... T>
void f(T... awaiters);缩写函数模板语法也是如此:
void f(Awaiter auto... awaiters);或者如果你有一个固定的数量,这特别没有意义:
template <Awaiter T, Awaiter U>
void f(T, U);即使在其他不适合它的上下文中,使用折叠表达式手动使用Awaiter似乎也更好。因此,我质疑是否有必要从合取这个概念开始。
https://stackoverflow.com/questions/63799653
复制相似问题