如何通过概念选择最佳约束函数模板? [英] How is the best constrained function template selected with concepts?

查看:82
本文介绍了如何通过概念选择最佳约束函数模板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在概念的演示中,显示了这样的内容:

In a presentation of concepts something like this was shown:

template <bidirectional_iterator It>
void sort(It begin, It end);            // #1

template <random_access_iterator It>
void sort(It begin, It end);            // #2



std::list<int> l{};
sort(l.begin(), l.end()); // #A  -> calls #1

std::vector<int> v{};
sort(v.begin(), v.end()); // #B  -> calls #2

通话 #A 很简单:只有 sort#1 是可行的,因为不满足约束 random_access_iterator ,因此它调用#1

For the call #A it's simple: only sort #1 is viable as the constraint random_access_iterator is not satisfied so it calls #1.

但对于通话 #B sort 是可行的,因为这两个约束(满足 random_access_iterator bidirectional_iterator )。那么,如何选择更有效率的 sort#2 ?演示者说它正好起作用。

But for the call #B both sorts are viable as both constraints (random_access_iterator and bidirectional_iterator are satisfied). So how is the "more efficient" sort #2 chosen? The presenter said "it just works".

推荐答案


那么效率更高如何 sort#2 是否被选择?

之所以有效,是因为存在部分约束上的排序(由 subsums 关系定义)。

It works because there is a partial ordering on constraints (defined by the subsumes relation).

sort#2 sort#1 相比,$ c>(具有 randomaccess_iterator 的那个)更受约束。 (具有 bidirectional_iterator 的人),因为 randomaccess_iterator 包含 bidirectional_iterator

sort #2 (the one with the randomaccess_iterator) is more constrained than sort #1 (the one with bidirectional_iterator) because randomaccess_iterator subsumes bidirectional_iterator:

template <class It>
concept bidirectional_iterator = requires /*...*/;

template <class It>
concept randomaccess_iterator = bidirectional_iterator<It> && requires /*...*/;

要使这项工作受到限制,必须在连词和析取词的语言水平上知道这一点。

To make this work constraints are aware at the language level of conjunctions and disjunctions.

确定一个声明是否比另一个约束更多的过程是这样的:约束规范化->约束包含关系->(定义)约束局部排序->(确定)声明之间的约束关系更多/更少。

The process for determining if a declaration is more or less constrained than another goes like this: Constraint normalization -> constraint subsumes relation -> (defines) constraint partial ordering -> (determines) declarations are more/less constraint relation.

简化,归一化是概念模板参数在约束的参数映射中的替代。

Simplified, normalization is the substitution of the concepts template parameters in the parameter mapping of constraints.

示例:

template <class T> concept integral        = std::is_integral_v<T>;
template <class T> concept signed_integral = integral<T> && std::is_signed_v<T>;
template <class T> concept integral_4      = integral<T> && sizeof(T) == 4;

void foo_1(integral auto)        // #0
void foo_1(signed_integral auto) // #1 
void foo_1(integral_4 auto)      // #2

auto test1()
{
    foo_1(std::uint16_t{});  // calls #0
    foo_1(std::uint32_t{});  // calls #2

    foo_1(std::int16_t{});   // calls #1
    //foo_1(std::int32_t{}); // error ambiguous between #1 and #2
}




  • 积分的普通形式是 std :: is_integral_v

  • signed_integral 的普通形式为 std :: is_integral_v< T> ∧std :: is_signed_v< T>

  • 正常形式 integral_4 std :: is_integral_v< T> ∧sizeof(T)== 4

    • the normal form of integral is std::is_integral_v<T>
    • the normal form of signed_integral is std::is_integral_v<T> ∧ std::is_signed_v<T>
    • the normal form integral_4 is std::is_integral_v<T> ∧ sizeof(T) == 4

      signed_integral 包含积分

      integral_4 包含积分

      #1 #0

      示例:

      template <class T> concept integral            = std::is_integral_v<T>;
      template <class T> concept signed_integral_sad = std::is_integral_v<T> &&
                                                           std::is_signed_v<T>;
      template <class T> concept integral_4_sad      = std::is_integral_v<T> && sizeof(T) == 4;
      
      
      void foo_2(integral auto)             // #0
      void foo_2(signed_integral_sad auto); // #1
      void foo_2(integral_4_sad auto);      // #2
      
      
      auto test2()
      {
          foo_2(std::uint16_t{});   // calls #0
          //foo_2(std::uint32_t{}); // error ambiguous between #0 and #2
      
          //foo_2(std::int16_t{});  // error ambiguous between #0 and #1
          //foo_2(std::int32_t{});  // error ambiguous between #0, #1 and #2
      }
      




      • 积分的正常形式为 std :: is_integral_v< T>

      • signed_integral_sad 的普通形式为 std :: is_integral_v< T> d std :: is_signed_v< T>

      • 正常形式 integral_4_sad std :: is_integral_v< T> ∧sizeof(T)== 4

        • the normal form of integral is std::is_integral_v<T>
        • the normal form of signed_integral_sad is std::is_integral_v<T> ∧ std::is_signed_v<T>
        • the normal form integral_4_sad is std::is_integral_v<T> ∧ sizeof(T) == 4
        • 但是有规则


          §13.5.1.2原子约束[temp.constr.atomic]


          1. 两个原子约束 e1 e2 是相同的由相同表达式的相同外观形成[...]

          1. Two atomic constraints, e1 and e2, are identical if they are formed from the same appearance of the same expression [...]


          3种范式的 std :: is_integral_v< T> 原子表达式在它们之间并不相同,因为它们不是由同一表达式形成的。因此:

          This means that the std::is_integral_v<T> atomic expressions from the 3 normal forms are not identical between them because they were not formed from the same expression. So:


          • 没有归类关系

          • 没有更多约束关系

          • there is no subsumes relation
          • there is no more constraint relation

          这会导致额外的歧义。


          §13.5.1约束[temp.constr.constr]


          1. 约束是一系列逻辑运算和操作数,它们指定模板参数的要求。
            逻辑运算的操作数是约束。
            约束分为三种类型:

          1. A constraint is a sequence of logical operations and operands that specifies requirements on template arguments. The operands of a logical operation are constraints. There are three different kinds of constraints:


          • (1.1)连词(13.5.1.1)

          • (1.2)析取(13.5.1.1)和

          • (1.3)原子约束(13.5.1.2)。

          §13.5.1.1逻辑运算[temp.constr.op]


          1. 在约束上有两个二进制逻辑运算:合取和析取。 [注意:这些逻辑运算没有相应的
            C ++语法。出于说明的目的,连词使用符号ed拼写为
            ,而析取符号使用∨]



          拼写



          §13.5.3约束归一化[temp.constr.normal]


          1. 表达式E的正常形式是约束(13.5.1),其定义如下:

          1. The normal form of an expression E is a constraint (13.5.1) that is defined as follows:


          • (1.1)表达式(E)的正则形式是
            的正则形式E

          • (1.2)表达式的正常形式 E1 || E2 E1 E2 析取(13.5.1.1)

          • (1.3) E1&& E2 E1 E2 的正常形式的连词

          • (1.4)
            a concept-id C 的普通形式是 C
            约束表达式的普通形式,代以 A1,A2,...,An 原子约束的参数映射中,对于
            C 的相应模板参数,分别使用$ c>。 [...]

          • (1.5)任何其他
            表达式 E 的范式是其表达式的原子约束是 E
            ,它们的参数映射是身份映射。

          • (1.1) The normal form of an expression ( E ) is the normal form of E.
          • (1.2) The normal form of an expression E1 || E2 is the disjunction (13.5.1.1) of the normal forms of E1 and E2.
          • (1.3) The normal form of an expression E1 && E2 is the conjunction of the normal forms of E1 and E2.
          • (1.4) The normal form of a concept-id C<A1, A2, ..., An> is the normal form of the constraint-expression of C, after substituting A1, A2, ..., An for C’s respective template parameters in the parameter mappings in each atomic constraint. [...]
          • (1.5) The normal form of any other expression E is the atomic constraint whose expression is E and whose parameter mapping is the identity mapping.

          获得约束表达式的正常形式的过程称为规范化。

          The process of obtaining the normal form of a constraint-expression is called normalization.







          §13.5.4通过约束的局部排序[temp.constr.order]


          1. 约束 P 包含约束 Q 当且仅当,对于 P 130 的每个析取从句 Pi code>, Pi 将每个结语<< c $ c> Qj 包含在
            中的结语范式 Q 的131 ,其中

          1. A constraint P subsumes a constraint Q if and only if, for every disjunctive clause Pi in the disjunctive normal form 130 of P, Pi subsumes every conjunctive clause Qj in the conjunctive normal form 131 of Q, where


          • (1.1)析取子句 Pi 包含连词 Qj
            当且仅当在 Pi 中存在原子约束 Pia Qj 中存在原子约束 Qjb
            ,使得 Pia
            包含 Qjb ,并且

          • (1.2)原子约束 A 在且仅当 A 和<$包含
            另一个原子约束 B c $ c> B
            是使用13.5.1.2。中描述的规则的相同

          • (1.1) a disjunctive clause Pi subsumes a conjunctive clause Qj if and only if there exists an atomic constraint Pia in Pi for which there exists an atomic constraint Qjb in Qj such that Pia subsumes Qjb, and
          • (1.2) an atomic constraint A subsumes another atomic constraint B if and only if A and B are identical using the rules described in 13.5.1.2.

          [示例:假设 A B
          是原子约束(13.5.1.2)。约束 A∧B 包含 A
          A 不包含 A∧B 。约束 A 包含 A∨B
          A∨B 不包含 A 。还要注意,每个约束
          都包含在内。 —结束示例]

          [Example: Let A and B be atomic constraints (13.5.1.2). The constraint A ∧ B subsumes A, but A does not subsume A ∧ B. The constraint A subsumes A ∨ B, but A ∨ B does not subsume A. Also note that every constraint subsumes itself. — end example]

          [注:包含关系定义了约束的部分排序。这种部分排序用于确定

          [Note: The subsumption relation defines a partial ordering on constraints. This partial ordering is used to determine


          • (2.1)非模板函数的最佳可行候选者(12.4.3),
          • >
          • (2.2)非模板函数的地址(12.5),

          • (2.3)模板模板参数的匹配(13.4.3),

          • (2.4)类模板专业化的部分排序(13.7.5.2),

          • (2.5)函数
            的部分排序模板(13.7.6.2)。

          • (2.1) the best viable candidate of non-template functions (12.4.3),
          • (2.2) the address of a non-template function (12.5),
          • (2.3) the matching of template template arguments (13.4.3),
          • (2.4) the partial ordering of class template specializations (13.7.5.2), and
          • (2.5) the partial ordering of function templates (13.7.6.2).

          -尾注]


          1. 声明 D1 至少受声明约束 D2 如果


          • (3.1) D1 D2 都是约束声明,而 D1
            相关约束包括 D2 ;或

          • (3.2) D2 没有关联的约束。

          • (3.1) D1 and D2 are both constrained declarations and D1’s associated constraints subsume those of D2; or
          • (3.2) D2 has no associated constraints.

          当<$ c时,声明 D1 比另一个声明 D2 受约束更多$ c> D1 至少受 D2 约束,而 D2 不在
          至少受 D1 约束。

          A declaration D1 is more constrained than another declaration D2 when D1 is at least as constrained as D2, and D2 is not at least as constrained as D1.






          130)当约束是子句的
          析取时,约束为析取范式,其中每个子句都是原子性
          约束的并集。 [示例:对于原子约束 A B C ,约束 A∧(B∨C)
          析取范式为(A∧B)∨
          (A∧C)
          。它的析取子句是(A∧B)(A∧C)。 — end
          示例]


          130) A constraint is in disjunctive normal form when it is a disjunction of clauses where each clause is a conjunction of atomic constraints. [Example: For atomic constraints A, B, and C, the disjunctive normal form of the constraint A ∧ (B ∨ C) is (A ∧ B) ∨ (A ∧ C). Its disjunctive clauses are (A ∧ B) and (A ∧ C). — end example]

          131)当约束是子句的
          连词时,约束为合取范式,其中每个子句是
          的原子约束。 [示例:对于原子约束 A B C ,则
          约束 A∧(B∨C)为合取范式。它的
          连词是 A (B∨C)。 —结束示例

          131) A constraint is in conjunctive normal form when it is a conjunction of clauses where each clause is a disjunction of atomic constraints. [Example: For atomic constraints A, B, and C, the constraint A ∧ (B ∨ C) is in conjunctive normal form. Its conjunctive clauses are A and (B ∨ C). — end example

          这篇关于如何通过概念选择最佳约束函数模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆