玩命加载中 . . .

43-模板化基类


学习处理模板化基类内的名称

如果基类是个模板类,直接调用基类中的方法会不能编译

class A {
public:
    void func() { cout << "class A" << endl; }
};

template<class T>
class Base {
public:
    void testBase() {
        T t;
        t.func();
    }
};

template<class T>
class Derive : public Base<T> {
public:
    void testDerive() {
        testBase();
    }
};

int main(int argc, char const *argv[])
{
    Derive<A> d;
    d.testDerive();
    return 0;
}

编译不过

$ g++ test-43.cpp -o test-43
test-43.cpp: In member function ‘void Derive<T>::testDerive()’:
test-43.cpp:30:9: error: there are no arguments to ‘testBase’ that depend on a template parameter, so a declaration of ‘testBase’ must be available

由于base class template可能被特化,而特化版本可能不提供和一般性template模板相同的接口。因此编译器往往拒绝在templated base class(模板基类)内寻找继承而来的名称

template<>
class Base<int> {
public:
    void testBase2();   // 特化版本没有testBase成员
};

解决方法有三种

解决方法的原理:对编译器承诺,base class template的任何版本(包括特化版本)都将支持一般版本所提供的的接口

  • 使用this指针调用
template<class T>
class Derive : public Base<T> {
public:
    void testDerive() {
        this->testBase();
    }
};
  • 使用using
template<class T>
class Derive : public Base<T> {
public:
    using Base<T>::testBase;    // 告诉编译器,testBase在基类中
    void testDerive() {
        testBase();
    }
};
  • 显式地指出基类

这种比较不好,无法使用动态绑定

template<class T>
class Derive : public Base<T> {
public:
    void testDerive() {
        Base<T>::testBase();    // 告诉编译器,testBase在基类中
    }
};

文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录