解决方式是 用this来调用父类成员。

那么, 如何理解问题产生的原因, 及为什么用this调用就可以呢?谢各位大神。


C++的模板中的名称会进行两次查找,称为两阶段查找(two-phase lookup)。

对于一个非依赖型名称(不以任何方式依赖于模板参数的名称),在模板声明进行解析的时候就会进行查找。但C++标准中规定(14.6.2 3),一个非受限的名称查找的时候将不会考虑依赖型的基类。所以

template&

struct B { int x; };

template&

struct X : B& { void foo() { x = 0; }};

查找不到就会错误。解决办法是把它变成一个依赖型名称:

template&

struct B { int x; };

template&

struct X : B& { void foo() { this-&>x = 0; }

// this是依赖型名称

};

或者

template&

struct B { int x; };

template&

struct X : B& { void foo() { B&::x = 0; } // B&是依赖型名称};

为什么要这么做(两阶段查找),我想大概有这么几个原因:

1 提前发现错误2 为了分离模板(这个理由已经失去价值)不过它也有缺点:1 让C++变得更加令人不知所措我的印象中VC现在都没有完全支持两阶段查找,轮子哥的回答似乎也证实了这一点。谁知道为什么呢。。
用this可读性不高,可以用这种办法

template &
class B
{
protected:
T data_;
};

template &
class D : public B&
{
public:
void test() {
do_something(B&::data_);
}
};


类模板能够承继也能够被承继。

1.在一个类模板中,一个非依靠型基类是指:无须知道模板实参就能够彻底确定类型的

基类。

例如:

template&

class Base{

public:

int basefield;

typedef int T;

};

class D1:public Base& &>{//实际上不是模板

public:

void f(){basefield = 3; }

};

template&

class D2:public Base&{

public:

void f() { basefield = 7; }//正常访问承继成员

T strange;//T是Base&::T,而不是模板参数

};

留意事项:关于模板中的非依靠类型而言,假如在他的派生类中查找一个非受限称号,

那就会先查找这个非依靠型基类,然后才会查找模板参数列表。

2.非依靠性称号不会在依靠基类中查找

template&

class Base{

public:

int basefield;

typedef int T;

};

template &

class DD:Base&{

public:

void f(){

basefield = 0;//problem

}

};

template&

class Base&{

public:

enum { basefield = 42 };//tricky

};

void g(DD& d){

d.f();//opps

}

//修正计划一

template &

class DD1:Base&{

public:

void f(){

this-&>basefield=0;//查找被延迟了

}

};

//修正计划二

template &

class DD2:Base&{

public:

void f(){

Base&::basefield=0;//查找被延迟了

}

};

假如运用修正计划二,假如原来的非受限非依靠型称号是被用于虚函数调用的话,

那么引进依靠性的限制的话,那么这种引进依靠性的限制将会近之虚函数调用,

从而也会改动程序的意义,当遇到第二种情况不适合的情况,能够选用计划一只听过,模板类,非类型形参,
非模板类和非类模板类应该是指不是模板类的一般类吧

模板是以template开端命名的函数或者类,比方
template& class A{T a;} 表明声明一个称号为A的模板类,其间的参数T是模板形参,他能够是int, float, char等,具体是什么类型,在类A创建目标的时分决议。比方 A& m;声明一个模板形参为int的类A的目标m,这时类A中的T a;中的a就是int型;同理A& n;表明声明一个模板形参为float的目标n

非类型形参,指的是模板中的模板形参不是运用class关键字界说的,而是运用C 内置类型界说的形参,比方template& class B{},其间的形参a就是非类型形参,他是运用的内置类型int声明的。

同理函数模板也有必要以template关键字开端,比方
template & void g(T a){}等。
留意:非类型模板形参一般不能用于模板函数中,当然你也能够运用没有强制规则


和一般的类界说静态成员相同,只不过要加上模板的声明。template &struct template_class {static int static_member;};template &int template_class&::static_member = 1;你的问题:data(ArrayInt(yr,y),ArrayInt(bot,y) )为什么能够这么写?data的括弧里边应该是两个ArrayInt的object,比方能够ArrayInt a,b; 然后再data(a,b)。可是ArrayInt(yr,y)和ArrayInt(bot,y)自身是结构函数,并不是实实在在的目标。
你都知道ArrayInt(yr,y)是一个结构函数了,结构函数回来的就是一个目标啊!莫非你一定要ArrayInt a = ArrayInt(yr,y); ArrayInt b = ArrayInt(bot,y);然后再data(a,b)才干了解么?
c 和java有点差异:java调用结构函数前面就需要加new ArrayInt a = new ArrayInt(yr,y)别搞混了
吐槽一下= =模板类 我以为是java的模板方法模式,父类调用子类的方法。
和一般的类界说静态成员相同,只不过要加上模板的声明。template &struct template_class {static int static_member;};template &int template_class&::static_member = 1;只听过,模板类,非类型形参,
非模板类和非类模板类应该是指不是模板类的一般类吧

模板是以template开端命名的函数或许类,比方
template& class A{T a;} 表明声明一个名称为A的模板类,其间的参数T是模板形参,他可所以int, float, char等,具体是什么类型,在类A创立目标的时分决议。比方 A& m;声明一个模板形参为int的类A的目标m,这时类A中的T a;中的a就是int型;同理A& n;表明声明一个模板形参为float的目标n

非类型形参,指的是模板中的模板形参不是运用class关键字界说的,而是运用C 内置类型界说的形参,比方template& class B{},其间的形参a就是非类型形参,他是运用的内置类型int声明的。

同理函数模板也有必要以template关键字开端,比方
template & void g(T a){}等。
留意:非类型模板形参一般不能用于模板函数中,当然你也能够运用没有强制规则


推荐阅读:
相关文章