在C++中继承模板类

sor*_*h-r 0 c++ inheritance templates

可能重复:
C++继承的模板类无权访问基类

我遇到了模板和继承问题.简单地说,我有一个模板类,我希望从中继承另一个模板类.我不明白为什么基类的成员在派生类中不可见?虽然不使用模板,但一切都按预期工作.例如:

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
};
Run Code Online (Sandbox Code Playgroud)

Naw*_*waz 8

这些变量是从属名称(有关详细信息,请参阅Dreaded Two-Phase Name Lookup),因此您需要使用thisas:

void doX(){ this->x++; this->y++; } 
Run Code Online (Sandbox Code Playgroud)

通常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++;} 
    //...
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,事实名称不能被查到的,直到base(这是一种类型定义Foo<T>)被实例化,变得更加明显(以人类的眼睛在我看来).

  • @ sorush-r:是的.这里需要*.实际上显式的`this->`告诉编译器在实例化基类时在**第二**阶段查找名称,因为这种情况使用两阶段名称查找机制. (2认同)

Mik*_*our 7

如果基类依赖于模板参数,则其成员在派生类定义中不可直接使用.在模板实例化之前,编译器不知道基类将包含什么,因此它不会从那里查找任何名称.

您可以强制它通过限定名称将名称视为成员:

void doX(){this->x++; Foo<T>::y++;}  // OK: both forms specify that it's a member
Run Code Online (Sandbox Code Playgroud)