调用 base class 函数时必须使用 class 名称?

Mandatory class name when calling base class' function?

为什么在尝试从同名的 Derived class' 函数调用 Base class' 模板函数时需要 Base class' 名称?

考虑这段代码:

struct Base
{
    template < typename >
    void foo() { }
};

struct Derived  : public Base
{
    void foo()
    {
        Base::foo<int>(); // PASSES
        foo<int>(); // FAILS!
    }
    void bar()
    {
        foo<int>(); // Passes if Derived::foo is not there and fails if it is there
    }
};

这符合标准吗? GCC 和 clang 在这里的行为方式相同。

这是隐藏姓名。

根据unqualified name lookup,

的规则

name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.

也就是说,在Derived的成员函数中,总是会找到Derived::foo然后名称查找停止,根本不会考虑Base::foo。然后你会得到这样的错误 foo is not a template.

您也可以使用using来解决问题。

struct Derived  : public Base
{
    using Base::foo;
    void foo()
    {
        Base::foo<int>(); // PASSES
        foo<int>(); // PASSES
    }
    void bar()
    {
        foo<int>(); // PASSES
    }
};