【问题标题】:calling static methods of a templated superclass调用模板化超类的静态方法
【发布时间】:2015-03-28 01:18:37
【问题描述】:

我有一个模板类A<T>,其中包含一个静态方法foo(),它返回一个A<T> *。我有一个子类B,它专门针对A<int>。

为避免代码重复,我希望 B 利用 A 的静态 foo() 方法。但是,下面会出现编译错误:error: cannot initialize return object of type 'B *' with an rvalue of type 'A<int> *') 但是B * 正好是A<int> *,不是吗?

有没有办法让B使用A的foo()方法?

template <typename T>
class A {
public:
  static A *foo() {
    // imagine complex code here
    return new A<T>();
  }
};

// B is a typed specialization of A
class B : public A<int> {
public:
  static B *foo() {
    return A<int>::foo();    // doesn't compile
  }
};

int main() {
  B *b = B::foo();
  (void)b;                      // suppress unused variable warning
}

【问题讨论】:

  • I'd like B to take advantage of A's static foo() method, A::foo() 是公开的,为什么要在B 中复制它?
  • 因为我省略了细节以保持示例简单:B::foo() 对A::foo() 返回的对象做了一些额外的事情。
  • " 但是 B * 正是 A *,不是吗?" 好吧,不!一点也不。 B 不是 A 的特化。 A&lt;int&gt; 是 B 的特化。 B 是一个继承自 A&lt;int&gt; 的类。这是一种独特的类型。

标签: c++ templates c++11 static-methods


【解决方案1】:

有没有办法创建一个类B,当我使用它时,它的意思是A&lt;int&gt;?

如果B是A&lt;int&gt;的别名,那么它就是A&lt;int&gt;的别名,而B::foo和A&lt;int&gt;::foo是一回事,而你真正想要的是让A&lt;int&gt;::foo做某事与原版A&lt;T&gt;::foo 相比,更多,但仍重用A&lt;T&gt;::foo 的代码。

换句话说,您需要对该成员函数进行显式特化。要重用原始版本的代码,只需将通用代码移至单独的函数即可:

template<class T>
struct A {
    static A<T> * foo_common() { 
        // common stuff 
        return nullptr;     
    }

    static A<T> * foo() { 
        // vanilla foo(); just call foo_common()
        return foo_common(); 
    }
};

// specialization of `foo` for A<int>
template<>
inline A<int>* A<int>::foo() { 
    auto p = foo_common(); 
    // extra stuff
    return p;
}

如果你想让B 表示A&lt;int&gt;,很简单:

using B = A<int>;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    相关资源
    最近更新 更多