考虑以下两个函数模板的重载 foo
:
template <typename T>
void foo(T) requires std::integral<T> {
std::cout << "foo requires integral\n";
}
template <typename T>
int foo(T) requires std::integral<T> && true {
std::cout << "foo requires integral and true\n";
return 0;
}
请注意两个约束之间的区别:第二个约束有一个额外的 && true
.直观地说,
true
在连词中是多余的(因为 X && true
只是 X
)。但是,看起来这在语义上有所不同,如 foo(42)
会 call the second overload .为什么会这样?具体来说,为什么第二个函数模板是更好的重载?
最佳答案
根据 [temp.constr.order] ,特别是 [temp.constr.order]/1和 [temp.constr.order]/3
/1 A constraint
P
subsumes a constraintQ
if and only if, [...] [ Example: Let A and B be atomic constraints. 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 ]/3 A declaration
D1
is at least as constrained as a declarationD2
if
- (3.1)
D1
andD2
are both constrained declarations andD1
's associated constraints subsume those ofD2
; or- (3.2) D2 has no associated constraints.
如果我们考虑
A
如 std::integral<T>
和 B
如 true
;然后:A ∧ B
这是 std::integral<T> && true
包含 A
, 即 std::integral<T>
, 这意味着对于以下声明:
// Denote D1
template <typename T>
void foo(T) requires std::integral<T> && true;
// Denote D2
template <typename T>
void foo(T) requires std::integral<T>;
D1
的相关约束包含 D2
的那些,因此 D1
至少与 D2
一样受约束.同时反向不成立,D2
至少不像 D1
那样受约束.这意味着,根据 [temp.constr.order]/4A declaration
D1
is more constrained than another declarationD2
whenD1
is at least as constrained asD2
, andD2
is not at least as constrained asD1
.
声明
D1
比声明更受约束 D2
, 和 D1
随后根据 [temp.func.order]/2 被重载解析选择为最佳匹配:Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph) and performing template argument deduction using the function type. The deduction process determines whether one of the templates is more specialized than the other. If so, the more specialized template is the one chosen by the partial ordering process. If both deductions succeed, the partial ordering selects the more constrained template (if one exists) as determined below.
关于c++ - 为什么将 "&& true"添加到约束会使函数模板成为更好的重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67006290/