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

What are the rules for ordering concept constrained functions in 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 操作),其中操作数是约束和概念分解为所谓的 原子约束 .为了简化 原子约束 是 none 折叠 "logical and expressions" 和 "logical or expressions" 的操作数,它们出现在约束和概念定义中。

我认为尝试更进一步会导致复制标准。所以这是最相关的标准部分 link [temp.constr]