在 C++20 中对概念约束函数进行排序的规则是什么?



我刚刚了解到C++概念比SFINAE优越得多,因为受概念约束的函数是有序的,这意味着受约束较多的函数被认为比约束较少的函数更匹配。

编译器究竟如何使用规则来估计函数的约束程度? 在混合无约束和约束过载时,这些规则如何与传统过载解决方案交互?

为了简单起见...,在重载解决过程中:

首先,所有在没有约束的情况下可行但未满足约束的功能都被视为不可行。

因此,可行重载集包含函数、模板函数和具有满足约束的约束模板化函数。

然后在第一步中选择最佳重载,而不考虑约束。在上述每个步骤中,编译器都会比较 2 个候选者,如果其中一个看起来比另一个更好,则认为该候选者比另一个更好匹配,而不考虑任何进一步的标准:

  1. 它首先考虑参数转换
  2. 然后,如果一个是模板而另一个不是,它会选择非模板
  3. 在此步骤中,必须有 2 个模板。它考虑一个是否比另一个更专业(约束在这里不发挥任何作用(
  4. 它考虑其中一个模板是否比另一个模板更受约束。

例如:

template <Concept1 T> foo(T&&);
template <Concept2 T> foo(const T&);
template <Concept3 T> foo(const T&);
void g(){
int i=10;
const int& j =i;
foo (j) // the compiler will check the 2 last foo 
//to see if one is more constrained than the other
foo (i) //the first foo is selected even if the second or third foo could look like they are more constrained
}

如果编译器可以证明,对于任何可能的模板参数集,如果满足 T1 的约束,则满足 T2 的约束,则模板 T1 比模板 T2 更受约束。它检查是否可以证明:

constraints of T1 statisfied  ==>  constraints of T2 satisfied

==>的意思是暗示。

要进行这样的演示,编译器非常有限。它将仅使用布尔代数的子集(仅andor运算(,其中操作数是约束和概念分解为所谓的原子约束。为了简化原子约束,出现在约束和概念定义中的未折叠的"逻辑和表达式"和"逻辑或表达式"的操作数。

我想尝试走得更远会导致复制标准。所以这里是最相关的标准部分的链接 [temp.constr]

最新更新