如果下面的类不是模板,我可以简单地x在derived课堂上.但是,使用下面的代码,我必须使用this->x.为什么?
template <typename T>
class base {
protected:
int x;
};
template <typename T>
class derived : public base<T> {
public:
int f() { return this->x; }
};
int main() {
derived<int> d;
d.f();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 为什么C++标准指定模板中的非限定名称是非依赖的?
例如
template<typename T>
class Base
{
public:
T x;
};
template<typename T>
class C : public Base<T>
{
public:
bool m() { return x == 0; } // Error: undeclared identifier 'x'
};
Run Code Online (Sandbox Code Playgroud)
引用一个关于如何克服限制的SO 问题的接受答案:
该标准指定模板中的非限定名称是非依赖的,并且必须在定义模板时查找.当时未知依赖基类的定义(可能存在基类模板的特化),因此无法解析非限定名称.
但是,引用和其他答案没有说明为什么这是标准指定的内容.这种限制的理由是什么?
您可能已经注意到gcc的更高版本对标准更严格(请参阅此问题)
应使用全名调用模板类的所有继承成员,即.
ParentClass<T>::member而不仅仅是member
但是我仍然有许多不尊重这一点的旧代码.using ParentClass<T>::member为每个类中的每个使用成员添加是非常痛苦的.有办法做点什么using ParentClass<T>::*吗?我希望这比在g ++中停用此检查更好,但如果现在有办法,我该如何停用它?
编辑:
根据C++ FAQ(谢谢......)这些是正确解决继承成员变量名称的唯一方法:
将呼叫从更改f()为this->f().由于这总是隐式依赖于模板,因此this->f是依赖的,因此查询将被推迟,直到模板实际被实例化为止,此时将考虑所有基类.
插入using B<T>::f; 就在打电话之前f().
将呼叫从f()更改为B<T>::f().
所以现在寻找正确的开关来停用全名解析......
我有以下代码:
template <typename T>
class ListBase
{
protected:
int _size;
public:
ListBase() {_size=0;}
virtual ~ListBase() {}
bool isEmpty() {return (_size ==0);}
int getSize() {return _size;}
virtual bool insert(int index, const T &item) = 0;
virtual bool remove(int index) = 0;
virtual bool retrieve(int index, T &item) = 0;
virtual string toString() = 0;
};
Run Code Online (Sandbox Code Playgroud)
我的第二个文件定义了一个子类:
#define MAXSIZE 50
template <class T>
class ListArray : public ListBase
{//for now to keep things simple use int type only later upgrade to template …Run Code Online (Sandbox Code Playgroud) 在下面的代码中,为什么T2会出现此错误‘m_t’ was not declared in this scope,而TB是正常的?
如何在仍然使用模板的情况下访问T2中的T1成员?
// All good
class TA
{
public:
TA() {}
protected:
int m_t;
};
class TB : public TA
{
public:
TB() {}
int get()
{ return m_t; }
protected:
};
// Error in T2
template<typename T>
class T1
{
public:
T1() {}
protected:
int m_t;
};
template<typename T>
class T2 : public T1<T>
{
public:
T2() {}
int get()
{ return m_t; }
protected:
};
Run Code Online (Sandbox Code Playgroud) 我想在父类中访问受保护的变量,我有以下代码,并且可以正常编译:
class Base
{
protected:
int a;
};
class Child : protected Base
{
public:
int b;
void foo(){
b = a;
}
};
int main() {
Child c;
c.foo();
}
Run Code Online (Sandbox Code Playgroud)
好的,现在我想将所有内容都模板化。我将代码更改为以下内容
template<typename T>
class Base
{
protected:
int a;
};
template <typename T>
class Child : protected Base<T>
{
public:
int b;
void foo(){
b = a;
}
};
int main() {
Child<int> c;
c.foo();
}
Run Code Online (Sandbox Code Playgroud)
并得到错误:
test.cpp: In member function ‘void Child<T>::foo()’:
test.cpp:14:17: error: ‘a’ was not declared …Run Code Online (Sandbox Code Playgroud) 可能有点懦弱的问题:我有两个类,并声明所有变量公开.为什么我不能从派生类访问变量?
g ++告诉我:vec3d.h:76:3:错误:'val'未在此范围内声明
template<typename TYPE>
class vec{
public:
TYPE *val;
int dimension;
public:
vec();
vec( TYPE right );
vec( TYPE right, int _dimension );
[etc]
template<typename TYPE>
class vec3d : public vec<TYPE>{
public:
vec3d() : vec<TYPE>( 0, 3 ){};
vec3d( TYPE right ) : vec<TYPE>( right, 3 ){};
vec3d( TYPE X_val, TYPE Y_val, TYPE Z_val ) : vec<TYPE>( 0, 3 ){
val[0] = X_val; //// <----------THIS ONE FAILS!
val[1] = Y_val;
val[2] = Z_val;
};
[etc]
Run Code Online (Sandbox Code Playgroud)