2015-03-28 8 views
0

У меня есть шаблонный шаблон A<T>, который содержит статический метод foo(), который возвращает A<T> *. У меня есть подкласс B, который просто специализируется на A<int>.вызов статических методов шаблона суперкласса

Чтобы избежать дублирования кода, я бы хотел, чтобы B воспользовался статическим методом foo(). Однако, следующее получает ошибку компиляции: error: cannot initialize return object of type 'B *' with an rvalue of type 'A<int> *') Но B * точно A<int> *, нет?

Есть ли способ использовать B для использования метода 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 
} 
+0

'Я хотел бы B использовать A статический метод foo(), 'A :: foo()' является общедоступным, почему вы дублируете его в 'B'? – billz

+0

Потому что я пропустил подробности, чтобы упростить пример: 'B :: foo()' выполняет некоторые дополнительные функции для объекта, возвращаемого 'A :: foo()'. –

+0

_ «Но B * точно A *, нет?» _ Ну, нет! Не за что. 'B' не является специализацией' A'. 'A ' является специализацией 'B'. 'B' - класс, который наследуется от' A '. Это отличный тип. –

ответ

0

is there a way to create a class B that, when I use it, means A<int> ?

Если B является псевдонимом для A<int>, то это псевдоним для A<int> и B::foo и A<int>::foo одно и то же, и что вы действительно хотите для A<int>::foo сделать что-то дополнительное по сравнению с ванилью A<T>::foo , но все равно повторяет код A<T>::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<int>, это просто:

using B = A<int>; 
Смежные вопросы