Daily C/C++ Dependent Names
今天这个文章会比较短,提一下我今天写代码时遇到的一个小问题
先看这样一段代码
template<typename T>
class A {
protected:
int number;
}
template<typename T>
class B: public A<T> {
public:
void foo() {
number = 10;
}
}
这段代码在编译的时候是会报错的
编译器会提示你,在B这个类中,找不到number这个变量
但是我们明显的可以看到,number是我们继承来的变量,为什么在B中会找不到呢?
先说理由
C++03 14.6.2
In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.
可以看到,对于类模板的继承,在类定义点的进行非依赖名称的查找期间,或者类模板实例化的过程中,基类是不会参与的
也就是说上面的number在查找的时候不会去找基类的域,所以我们就会得到找不到number的报错
可以这样理解,number是一个非依赖的变量,因为他在类模板中不依赖模板的类型,而是一个固定的类型,所以编译器会对他进行提前的查找
这个叫做两阶段查找
他们会在模板被定义的时候进行决议,而非实例化的时候。所以我个人感觉是因为在决议number的时候,基类还没有实例化,所以基类就不会参与决议。
这样做的好处就是如果我们有类似的错误,就可以在模板实例化之前找到他,从而提升速度
那么解决方法就是将我们的变量变成依赖性的变量,即我们可以显示指定作用域,即A<T>::number = 10
。
或者使用this,在cppreference中,this是类型待决表达式。所以使用this->number
可以让number依赖于this,而this依赖于类模板。所以这时候number也变成了依赖性变量
文章评论