两阶段查找:可以轻松地混合继承和模板

Ant*_*ine 4 c++ inheritance templates

简介: C++标准区分了依赖于模板参数的符号名称和不符合模板参数的名称,即所谓的两阶段名称查找(参见此处).定义模板时,将尽快解析非依赖名称.另一方面,从属名称仅在模板实例时解析.

例:

template<class T> struct Base {
    typedef T type;
    static const int n = 3;
    virtual int f() = 0;
    int f(int x) { return x * 2; }
};

// doesn't compile!
template<class T> struct Derived : Base<T> {
    type field;         // The compiler doesn't know Base<T>::type yet!
    int f() { return n; } // the compiler doesn't know n yet, and f(int) is maksed!
};
Run Code Online (Sandbox Code Playgroud)

目前,我所做的是这样定义Derived:

template<class T> struct Derived : Base<T> {
    typedef Base<T> Parent;
    typedef typename Parent::type type; // correct but
    using Parent::n;                    // boring, long
    using Parent::f;                    // and harder to maintain
    type field;
    int f() { return n; }
};
Run Code Online (Sandbox Code Playgroud)

对我来说,面向对象编程的主要目标之一是减少代码重复; 这种失败的目的......

问题:是否有另一种方法Derived通过使用一些我不知道的语法或一个聪明的技巧来定义?我喜欢这样的事情:

template<class T> struct Derived : Base<T> {
    using Base<T>::*; // I promise I won't do strange specializations of Base<T>
    type field;
    int f() { return n; }
};
Run Code Online (Sandbox Code Playgroud)

编辑澄清:也许我不够具体.想象一下,你有大约十个typedef/fields /函数Base,以及几十个派生类,每个类的特定代码少于5行.这意味着大多数代码都包含重复的typedef和using子句,我知道没有办法完全避免这种情况,但我希望尽量减少这些重复的代码.

感谢任何想法,使这更容易编写和维护!

Mik*_*our 5

T field;
Run Code Online (Sandbox Code Playgroud)

那应该不是问题; T是模板参数本身,而不是依赖名称.

return n;
Run Code Online (Sandbox Code Playgroud)

这确实是一个问题,因为它是一个依赖名称,并且不知道是成员.最简单的解决方案是

return this->n;
Run Code Online (Sandbox Code Playgroud)

Base<T>::n并且Derived::n也会工作,但我不想复制类名.

UPDATE

type field;
Run Code Online (Sandbox Code Playgroud)

不幸的是,没有比简单地访问依赖类型名称的技巧了

typename Base<T>::type field;
Run Code Online (Sandbox Code Playgroud)