c++ - 为什么将 "&& true"添加到约束会使函数模板成为更好的重载?

标签 c++ language-lawyer c++20 c++-concepts

考虑以下两个函数模板的重载 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 constraint Q if and only if, [...] [ Example: Let A and B be atomic constraints. 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 ]

/3 A declaration D1 is at least as constrained as a declaration D2 if

  • (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.

如果我们考虑 Astd::integral<T>Btrue ;然后:
  • 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]/4

    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.


    声明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/

    相关文章:

    c++ - 将 C++ 对象传递给它自己的构造函数是否合法?

    c++ - gcc 使用 std::initializer_list 调用构造函数而不是复制省略,而 clang 则不会。哪个编译器是正确的?

    C++ 概念 : checking for template instantiation

    c++ - 我可以让 lambda 推断出变体返回类型吗?

    c++ - 循环调用 boost io_service poll

    c++ - Visual Studio 平台工具集与 Windows SDK

    c - Linux 内核的 __is_constexpr 宏

    c++ - std::getline 部分读取第一行和最后一行并设置 eof 位

    c++ - 大括号初始值设定项列表中是否允许显式转换运算符?

    C++ 协程 : call a coroutine function without co_await