Marvin's Blog【程式人生】

Ability will never catch up with the demand for it

08 Jul 2021

C++标准文稿阅读【一】:Concepts

temp.decls

concept是一个模板用于在模板参数上定义约束。

concept-definition:
  concept concept-name = constraint-expression;

对于concept-definition有若干注意点,特别值得关注的而是:

  • constraint-expression是unevalauted operand
  • concept的第一个模板参数是其prototype parameter。一个type concept是这样的,其prototype parameter是一个类型的模板参数。

temp.constr

一个模板声明,或者一个模板化的函数声明可以通过requires-clause来约束其使用。约束是以constraint-expression形式提供:

constraint-expression:
    logical-or-expression

约束也可以通过type-constraint的方式出现在template-parameter-list或者parameter-type-list中。

段3略。

temp

requires-clause:
    requires constraint-logical-or-expression

constraint-logical-or-expression:
    constraint-logical-and-expression
    constraint-logical-or-expression || constraint-logical-and-expression

constraint-logical-and-expression:
    primary-expression
    constraint-logical-and-expression && primary-expression 

requires-clause是一堆or或者and的递归形式,最终转化成primary-expression。

expr

 primary-expression:
    literal
    this
    ( expression )
    id-expression
    lambda-expression
    fold-expression
    requires-expression 

expr.prim.req

requires-expression提供一个简洁的方法来描述对于模板参数的需求,使其可以通过名字查找或者通过类型和表达式的属性的检查来判定需求是否满足。

requires-expression:
    requires requirement-parameter-list(opt) requirement-body 

requirement-parameter-list:
    ( parameter-declaration-clause ) 

requirement-body:
    { requirement-seq } 

requirement-seq:
    requirement
    requirement-seq requirement 

requirement:
    simple-requirement
    type-requirement
    compound-requirement
    nested-requirement 
simple-requirement
    expression ;

例子:

template<typename T> concept C =
  requires (T a, T b) {
    a + b;          // C<T> is true if a + b is a valid expression
  };
 type-requirement:
    typename nested-name-specifier(opt) type-name ; 

例子:

template<typename T, typename T::type = 0> struct S;
template<typename T> using Ref = T&;

template<typename T> concept C = requires {
  typename T::inner;    // required nested member name
  typename S<T>;        // required valid ([temp.names]) template-id;
                        // fails if T​::​type does not exist as a type to which 0 can be implicitly converted
  typename Ref<T>;      // required alias template substitution, fails if T is void
};
 compound-requirement:
    { expression } noexcept(opt) return-type-requirement(opt) ;
return-type-requirement:
    -> type-constraint 

例子:

requires {
  { E1 } -> C;
  { E2 } -> D<A1, , An>;
};

等同于:

requires {
  E1; requires C<decltype((E1))>;
  E2; requires D<decltype((E2)), A1, , An>;
};
 nested-requirement:
    requires constraint-expression ; 

例子:

template<typename U> concept C = sizeof(U) == 1;

template<typename T> concept D = requires (T t) {
  requires C<decltype (+t)>;
};

上述例子D<T>sizeof(decltype (+t)) == 1被满足。

例子:

template<typename T> concept C = requires (T a) {
  requires sizeof(a) == 4;      // OK
  requires a == 0;              // error: evaluation of a constraint variable
};

其他参考

(暂时完了)