and*_*ewz 38 c++ inheritance templates
为什么C++编译器不能识别它g()并且b是Superclass此代码中看到的继承成员:
template<typename T> struct Superclass {
protected:
int b;
void g() {}
};
template<typename T> struct Subclass : public Superclass<T> {
void f() {
g(); // compiler error: uncategorized
b = 3; // compiler error: unrecognized
}
};
Run Code Online (Sandbox Code Playgroud)
如果我简化Subclass并Subclass<int>从那时继承它就会编译.它还会编译时完全限定g()为Superclass<T>::g()和Superclass<T>::b.我正在使用LLVM GCC 4.2.
注意:如果我在超类中创建g()并b公开它仍然会失败并出现相同的错误.
Kon*_*lph 49
这可以通过使用以下方法将名称拉入当前范围来修改using:
template<typename T> struct Subclass : public Superclass<T> {
using Superclass<T>::b;
using Superclass<T>::g;
void f() {
g();
b = 3;
}
};
Run Code Online (Sandbox Code Playgroud)
或者通过this指针访问限定名称:
template<typename T> struct Subclass : public Superclass<T> {
void f() {
this->g();
this->b = 3;
}
};
Run Code Online (Sandbox Code Playgroud)
或者,正如您已经注意到的那样,通过限定全名.
这是必要的原因是C++不考虑用于名称解析的超类模板(因为那时它们是依赖名称,并且不考虑依赖名称).它在您使用时有效,Superclass<int>因为它不是模板(它是模板的实例化),因此它的嵌套名称不是依赖名称.
Ton*_*roy 14
Konrad的回答并没有要求或回答所有这些中的最终"为什么".这不仅仅是C++委员会随意说"嘿,放弃依赖的名字,无论如何都没有人喜欢它们".相反,编译器甚至在它们被实例化之前就对模板进行了一些检查,并且在它知道T之前它不能理解g()或b,因为它不能 - 通常 - 在可能的特化之间进行选择.基类(例如SuperClass<X>可以具有int b同时SuperClass<Y>具有void b()和SuperClass<Z>不具有b在所有).更明确的形式只是说"相信我 - 这必须来自实例化时的基类(否则会有编译器错误)".
| 归档时间: |
|
| 查看次数: |
16281 次 |
| 最近记录: |