我试图在模板类中使用嵌套类。请参阅下面的代码段:
template <class T>
class OutterTemplate {
public:
class InnerBase {
protected:
const char* name_;
public:
virtual void print() {
cout << name_ << endl;
}
void setName(const char* n) {
name_ = n;
}
};
private:
class Inner : public InnerBase {
public:
virtual void print() {
cout << name_;
cout << " and ";
InnerBase::print();
}
};
public:
static InnerBase* getInner() {
return new Inner();
}
};
int main() {
auto q = OutterTemplate<int>::getInner();
q->setName("Not working");
q->print();
}
我在尝试编译此代码时遇到错误“错误:'name_'未在此范围内声明”。我检查“outter”是不是模板类,没有这样的问题。任何人都可以解释为什么模板类中的这个错误以及如何在模板类中嵌套类的情况下启用对基类成员的访问?
答案 0 :(得分:1)
标准在这一点上非常明确:
14.6.2从属名称[temp.dep]
3在类或类模板的定义中,如果是基类 取决于模板参数,不检查基类范围 在不完整的名称查找期间,或者在定义的位置 类模板或成员或在类的实例化期间 模板或成员。
此处,您的OutterTemplate<T>::InnerBase
是OutterTemplate<T>::Inner
的从属基类,cout << name_;
涉及非限定名称查找。这意味着不会检查InnerBase
。添加this->
可以解决这个问题:
14.6.2.1依赖类型[temp.dep.type]
7对于给定的模板参数集,如果是a的特化 模板实例化,引用当前成员 使用quali fi ed-id或类成员访问表达式进行实例化, quali fi-id或类成员访问表达式中的名称是 在模板实例化上下文中查找。
由于this->
是类成员访问表达式,这意味着name_
将在OutterTemplate<T>::Inner
实例化的位置被查找,此时name_
将是{{1}}在基类中找到。