可能重复:
C++ Inherited template classes don't have access to the base class
我遇到模板和继承问题。简单地说,我有一个模板类,我希望从中继承另一个模板类。我不明白为什么基类的成员在派生类中不可见?虽然不使用模板,但一切都按预期工作。例如:
template <typename T>
class Foo
{
public:
T x;
T y;
void doX(){ x = x+1; }
void doY(){y++;}
protected:
T a;
T b;
void doA(){a++;}
};
template <typename T>
class Bar : public Foo<T>
{
public:
void doX(){x++; y++;} // ERROR
void doY(){x++; y++;} // ERROR
void doA(){a++;b++;} // ERROR
};
答案 0 :(得分:8)
这些变量是依赖名称(详情请参阅The Dreaded Two-Phase Name Lookup),因此需要使用this
作为:
void doX(){ this->x++; this->y++; }
通常this->
不是必需的,因为它是隐式的。但这里必需。实际上,显式this->
告诉编译器在实例化基类时在第二阶段查找名称,因为这种情况使用两阶段名称查找机制。
或者你可以用基类来限定它们:
template <typename T>
class Bar : public Foo<T>
{
typedef Foo<T> base; //add this friendly typedef!
public:
void doX(){ base::x++; base::y++;}
//...
};
在这种情况下,无法查找名称直到base
(Foo<T>
的 typedef )被实例化的事实变为更多在我看来很明显(对于人的眼睛)。
答案 1 :(得分:7)
如果基类依赖于模板参数,则其成员在派生类定义中不能直接使用。在模板实例化之前,编译器不知道基类将包含什么,因此它不会从那里查找任何名称。
您可以通过限定名称强制它将名称视为成员:
void doX(){this->x++; Foo<T>::y++;} // OK: both forms specify that it's a member
答案 2 :(得分:3)
在派生类函数中写下这个 - &gt; x,this-&gt; y而不是x,y。
答案 3 :(得分:1)
尝试使用基类范围引用变量:
Foo<T>::x
或使用this
this->x