C ++概念如何组合概念?

how can a c++ concept combine concepts?

我继承了以下内容:

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

作为,您想要:

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 似乎更好。所以我质疑连词概念的必要性。