A.H
template <typename T>
class A
{
public:
int a;
}
b.h
template <typename T>
class B : public A<T>
{
public:
int f();
}
template <typename T>
int B<T>::f()
{
int t;
t = this->a; //Okay
t = a //Error
return 0;
}
为什么我不使用this->
时会发生错误?
我可以使用某种方法省略this->
吗?
(我修正了一些错误)
答案 0 :(得分:12)
模板实例化有两个阶段(“两阶段名称查找”)。
在第一阶段,解析所有非依赖名称(查找)。在第二阶段,依赖名称得到解决。
依赖名称是依赖于模板参数的名称,例如:
template <typename T>
void foo() {
x = 0; // <- Non-dependent, nothing in that refers to "T".
// Thus looked up in phase 1, therefore, an 'x' must be
// visible.
T::x = 0; // <- Dependent, because it depends on "T".
// Looked up in phase 2, which is when it must be visible.
}
现在,你写道:
t = this->a; //Okay
t = a //Error
这正是我所描述的。在好的术语中,在第2阶段查找t
,
因为this
取决于模板参数。
在阶段1中查找错误的术语,因为该名称中的任何内容都不依赖于模板参数。
但是在阶段1中,没有a
可见,因为编译器无法内省基类模板
在阶段1中,因为模板可以是专用的并且在实例化时,
它可以远离主模板声明,另一个专业化
没有a
的,可能是可见的。
示例:
template <typename T>
struct Base {
};
template <typename T>
struct Derived : Base<T> {
void foo() {
this->a = 0; // As is valid. `this->a` is looked up in phase 2.
}
};
template <> struct Base<int> {
int a;
};
int main ()
{
// The following declarations trigger phase 2 lookup.
Derived<int> di; // valid, because a later specialized
// Base<int> is used and all symbols
// are resolved.
Derived<float> df; // not valid
}
顺便说一下,我曾经在我的低频博客上写过 this-> is not only a matter of style 。
答案 1 :(得分:1)
B
是一个模板,因此它的名称是非依赖的,因此必须在定义模板时查找,而不是在实例化时查找。但是,在定义模板时,依赖名称是未知的(可能存在目前尚未见过的基类模板A
的特化),编译器无法将非限定名称解析为基类。您可以通过this->
资格认证将该名称带入当前范围,在其前面添加A<T>::
或using
声明:
template <typename T>
class B : public A<T>
{
public:
using A<T>::a;
int f();
};
另请注意,您在班级声明后遗漏了分号,以及标有// Error
评论的行。