在派生类中使用约束模板基成员函数,应该隐藏哪一个?

Oli*_*liv 6 c++ constraints using-declaration language-lawyer c++20

让我们考虑下面的代码,其中base成员在derived类中声明。GCC 和 Clang 不同意隐藏哪个成员:

template <class T>
concept C = true;

struct base
    {
    template <class T>
    void foo0 (T&&);

    template <class T>
    void foo1(T&&) requires C<T>;

    template <C T>
    void foo2(T&&);

    void foo3(C auto &&);

    template <C T, class U>
    void foo4(T&&, U&&);

    template <C T, class U>
    void foo5(T&&, U&&);
    };

struct derived
    : base
    {
    using base::foo0;
    using base::foo1;
    using base::foo2;
    using base::foo3;
    using base::foo4;
    using base::foo5;

    template <class T>
    void foo0(T&&);

    template <class T>
    void foo1(T&&);

    template <class T>
    void foo2(T&&);

    void foo3(auto &&);

    template <class T, class U>
    void foo4(T&&, U&&);

    template <class T, class U>  //inversed template parmeter order
    void foo5(U&&, T&&);         
    };
Run Code Online (Sandbox Code Playgroud)

derived成员函数调用,GCC和锵并不总是同意其功能应该被称为:(编译探险链接)

void g(derived d, int i) //                              Description of the difference
    {//Function called       |  by GCC   |  by Clang   | between base and derived member
                         //  -----------------------------------------              
    d. foo0(i);          //  |  derived  |  derived    | same signature
    d. foo1(i);          //  |  base     |  base       | trailing require clause
    d. foo2(i);          //  |  base     |  derived    | constrained template parameter
    d. foo3(i);          //  |  base     |  derived    | constrained function parameter
    d. foo4(i,i);        //  |  base     |  derived    | constrained template parameter
    d. foo5(i,i);        //  |  base     |  base       | reversed template parameter order
                                                            // with constraint.
    }
Run Code Online (Sandbox Code Playgroud)

从道德上讲,我不明白foo1 foo2foo3应该是不同的情况。

哪个编译器是对的?

指定是否隐藏基成员声明的标准段落是[namespace.udecl]/14

当 using 声明器将基类的声明引入派生类时,派生类中的成员函数和成员函数模板将覆盖和/或隐藏具有相同名称的成员函数和成员函数模板,参数类型列表 ([dcl .fct])、尾随 requires 子句(如果有)、cv 限定符和 ref 限定符(如果有),在基类中(而不是冲突)。这种隐藏或覆盖的声明被排除在 using-declarator 引入的声明集中。

在第一次阅读之后,看起来 Clang 正在应用这封信的标准。但...

但是这里的字母是什么意思?没有模板头的模板的等效参数类型列表是什么意思?考虑 的情况foo5,很明显 Clang 考虑了模板头,至少是模板参数顺序。