如何通过概念选择最佳约束函数模板? [英] How is the best constrained function template selected with concepts?
问题描述
在概念的演示中,显示了这样的内容:
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 sort
s 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 $ c与
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
isstd::is_integral_v<T>
- the normal form of
signed_integral
isstd::is_integral_v<T> ∧ std::is_signed_v<T>
the normal form
integral_4
isstd::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
isstd::is_integral_v<T>
- the normal form of
signed_integral_sad
isstd::is_integral_v<T> ∧ std::is_signed_v<T>
- the normal form
integral_4_sad
isstd::is_integral_v<T> ∧ sizeof(T) == 4
- 两个原子约束
e1
和e2
是相同的由相同表达式的相同外观形成[...] - Two atomic constraints,
e1
ande2
, are identical if they are formed from the same appearance of the same expression [...] - 没有归类关系
- 没有更多约束关系
- there is no subsumes relation
- there is no more constraint relation
-
约束是一系列逻辑运算和操作数,它们指定模板参数的要求。
逻辑运算的操作数是约束。
约束分为三种类型: 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)。
- 在约束上有两个二进制逻辑运算:合取和析取。 [注意:这些逻辑运算没有相应的
C ++语法。出于说明的目的,连词使用符号ed拼写为
,而析取符号使用∨] -
表达式E的正常形式是约束(13.5.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-idC
的普通形式是 C
的
约束表达式的普通形式,代以A1,A2,...,An $ c在每个
原子约束的参数映射中,对于
C
的相应模板参数,分别使用$ c>。 [...] - (1.5)任何其他
表达式E
的范式是其表达式的原子约束是E
和
,它们的参数映射是身份映射。 - (1.1) The normal form of an expression
( E )
is the normal form ofE
. - (1.2) The normal form of an expression
E1 || E2
is the disjunction (13.5.1.1) of the normal forms ofE1
andE2
. - (1.3) The normal form of an expression
E1 && E2
is the conjunction of the normal forms ofE1
andE2
. - (1.4) The normal form of
a concept-id
C<A1, A2, ..., An>
is the normal form of the constraint-expression ofC
, after substitutingA1, A2, ..., An
forC
’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 isE
and whose parameter mapping is the identity mapping. -
约束
P
包含约束Q
当且仅当,对于P 130 的每个析取从句
包含在Pi
code>,Pi
将每个结语<< c $ c> Qj
中的结语范式Q
的131 ,其中 A constraint
P
subsumes a constraintQ
if and only if, for every disjunctive clausePi
in the disjunctive normal form 130 ofP
,Pi
subsumes every conjunctive clauseQj
in the conjunctive normal form 131 ofQ
, 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 clauseQj
if and only if there exists an atomic constraintPia
inPi
for which there exists an atomic constraintQjb
inQj
such thatPia
subsumesQjb
, and - (1.2) an atomic constraint
A
subsumes another atomic constraintB
if and only ifA
andB
are identical using the rules described in 13.5.1.2. - (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).
-
声明
D1
至少受声明约束D2
如果 - (3.1)
D1
和D2
都是约束声明,而D1
的
相关约束包括D2
;或 - (3.2)
D2
没有关联的约束。 - (3.1)
D1
andD2
are both constrained declarations andD1
’s associated constraints subsume those ofD2
; or - (3.2)
D2
has no associated constraints.
但是有规则
§13.5.1.2原子约束[temp.constr.atomic]
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:
这会导致额外的歧义。
§13.5.1约束[temp.constr.constr]
§13.5.1.1逻辑运算[temp.constr.op]
拼写
§13.5.3约束归一化[temp.constr.normal]
获得约束表达式的正常形式的过程称为规范化。
The process of obtaining the normal form of a constraint-expression is called normalization.
§13.5.4通过约束的局部排序[temp.constr.order]
[示例:假设
A
和B
是原子约束(13.5.1.2)。约束A∧B
包含A
,
但A
不包含A∧B
。约束A
包含A∨B
,
但A∨B
不包含A
。还要注意,每个约束
都包含在内。 —结束示例][Example: Let
A
andB
be atomic constraints (13.5.1.2). The constraintA ∧ B
subsumesA
, butA
does not subsumeA ∧ B
. The constraintA
subsumesA ∨ B
, butA ∨ B
does not subsumeA
. 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
-尾注]
当<$ c时,声明
D1
比另一个声明D2
受约束更多$ c> D1 至少受D2
约束,而D2
不在
至少受D1
约束。A declaration
D1
is more constrained than another declarationD2
whenD1
is at least as constrained asD2
, andD2
is not at least as constrained asD1
.
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
, andC
, the disjunctive normal form of the constraintA ∧ (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
, andC
, the constraintA ∧ (B ∨ C)
is in conjunctive normal form. Its conjunctive clauses areA
and(B ∨ C)
. — end example这篇关于如何通过概念选择最佳约束函数模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
-
- the normal form of