概念能否与模板模板参数一起使用?

7

让我们考虑以下代码:

#include <concepts>

template<typename X>
struct Concrete_M {
  X f() const { return X{}; }
};

struct Concrete_X {};

template<typename T, typename X>
concept M = requires (T t)
  {
   { t.f() } -> std::convertible_to<X>;
  };

template<M<Concrete_X>>
struct C {};

const C<Concrete_M<Concrete_X>> c{};

我可以使用下面这个模板参数T吗?

template<template<typename> typename T, typename X>
concept M = requires (T<X> t)
  {
   { t.f() } -> std::convertible_to<X>;
  };

我该如何更改?

template<M<Concrete_X>>
struct C {};

const C<Concrete_M<Concrete_X>> c{};

如何正确地使用更新的概念 M?我正在寻找像这样的东西:

template<typename X, /* ... */>
struct C {};

const C<Concrete_X, /* ... */> c{};

但我不明白在 /* ... */ 注释之间应该放什么。 我尝试过:

template<typename X, M<X>>
struct C {};

const C<Concrete_X, Concrete_M<Concrete_X>> c{};

但是GCC 10.0.1会引发一个错误:
(...) 'M'没有限制类型(...)
1个回答

10

概念的短手类型约束语法:

template <Concept T>
struct C { };

这个只适用于那些 Concept 的第一个模板参数是类型参数的情况。如果不是这种情况,你就必须使用长形式语法:一个 requires-clause

template <template <typename> class Z>
    requires M<Z, Concrete_X>
struct C {};

我最初示例的等效长表单是:

template <typename T> requires Concept<T>
struct C { };

长表单和短表单指的是同一件事情 - 这里没有功能上的区别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接