c ++概念如何结合概念?

问题描述

我继承了以下内容

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

也许只是一个简单的语法问题,但是我发现很难找到一个示例,该示例显示了如何基于可变模板概念参数创建概念。

任何帮助表示赞赏!

解决方法

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

作为HTNW points out,您需要:

template <typename ...T>
concept IsAwaitables =  (IsAwaiter<T> && ...);

但是,实际上,您是否甚至需要这个概念?您可以直接使用IsAwaiter。大概应该将其命名为Awaiter-概念的典型约定是将它们命名为名词而不是问题(例如RangeIsRange)。

如果要使用参数包,则还是要使用它:

template <Awaiter... T>
void f(T... awaiters);

与缩写功能模板语法相同:

void f(Awaiter auto... awaiters);

或者如果您有固定的数量,则这毫无意义:

template <Awaiter T,Awaiter U>
void f(T,U);

即使在不合适的其他情况下,最好还是手动使用Awaiter和fold-expression。因此,我对连词概念的开头提出了疑问。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...