对依赖基类成员的不限定访问会导致"A declaration of [x] must be available"

Unqualified access to member of dependent base class results in "A declaration of [x] must be available"

本文关键字:of declaration available be must 成员 基类 依赖 访问      更新时间:2023-10-16

代码:

// test3.cpp
#include <stack>
using namespace std;
template<typename T>
struct ptr_stack_tp;
template<typename T>
struct ptr_stack_tp<T*> : public stack<T*>
{
    ~ptr_stack_tp()
    {
        while (!empty()) {
            operator delete(top());
            pop();
        }
    }
};
int main()
{}

错误消息(gcc 4.7.2(:

test3.cpp: In destructor 'ptr_stack_tp<T*>::~ptr_stack_tp()':
test3.cpp:15:23: error: there are no arguments to 'empty' that depend on a template parameter, so a declaration of 'empty' must be available [-fpermissive]
test3.cpp:15:23: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
test3.cpp:16:33: error: there are no arguments to 'top' that depend on a template parameter, so a declaration of 'top' must be available [-fpermissive]
test3.cpp:17:17: error: there are no arguments to 'pop' that depend on a template parameter, so a declaration of 'pop' must be available [-fpermissive]

函数empty()top()pop()std::stack的函数,那么,为什么gcc找不到它们呢?

您应该通过this指针显式调用类模板中的基类成员函数。

// ...
template<typename T>
struct ptr_stack_tp<T*> : public stack<T*>
{
    ~ptr_stack_tp()
    {
        while (!this->empty()) {
        //      ^^^^^^
            operator delete(this->top());
            //              ^^^^^^
            this->pop();
        //  ^^^^^^
        }
    }
};
// ...

这是由于模板的两阶段名称查找工作方式造成的。如果没有this->间接寻址,编译器将试图将不合格的名称解析为全局函数的名称。由于不存在名为empty()top()pop()的全局函数,编译器将发出错误。

当您使用this->时,编译器会将名称查找延迟到模板实际实例化的那一刻:此时,对基类成员的函数调用将被正确解析。