【问题标题】:how can a c++ concept combine concepts?c++ 概念如何结合概念?
【发布时间】:2020-09-08 18:26:23
【问题描述】:

我继承了以下内容:

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

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

任何帮助表示赞赏!

【问题讨论】:

  • (IsAwaiter&lt;AWAITABLES&gt; &amp;&amp; ...)?
  • std::conjunction 会打破包容顺便说一句。
  • 很遗憾,编译器还不喜欢这个:(。模板元编程~.
  • 根据您的建议,我尝试了concept IsAwaitables = typename std::conjunction(IsAwaiter&lt;AWAITABLES&gt; &amp;&amp; ...)::type;,但编译器以/home/dja/sandbox/experimental/rubicon/player/api/player/detail/IsAwaiter.h:43:24: error: no viable constructor or deduction guide for deduction of template arguments of 'conjunction' 响应。我想这就是你的建议..
  • 你为什么使用conjunction

标签: c++ c++20 variadic c++-concepts


【解决方案1】:

std::conjunction 用于类型特征。 std::conjunction&lt;IsAwaiter&lt;AWAITABLES&gt;...&gt; 是具有成员 static bool value = (IsAwaiter&lt;AWAITABLES&gt;::value &amp;&amp; ...) 的类型,其中每个 IsAwaiter&lt;AWAITABLES&gt; 本身都应该是具有自己的 static bool 成员 value 的类型特征。当IsAwaiter&lt;AWAITABLES&gt; 是一个概念时,这是荒谬的,因为概念不是类型特征。它们是“只是”布尔值。使用折叠表达式。

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。这似乎是一个相当常见的用例,所以希望其他人也觉得它有用。
【解决方案2】:

作为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 和折叠表达式似乎更好。所以我质疑连词概念的必要性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多