带有抽象基类的子类的模板特化

C++ Template specialization for subclasses with abstract base class

本文关键字:子类 抽象 基类      更新时间:2023-10-16

假设我有一个纯抽象基类。类模板实现这个接口,并且是专门化的。现在,我的问题是这个专门化应该能够处理专门化的子类。所以,我尝试了enable_if,但随后子类最终被抽象…我怎么才能避开这个问题呢?

由例子:

// This example doesn't work because a subclass of A does not satisfy the
// specialization for B<T>::foo()
class A {
public:
    virtual void foo() = 0;
};
template <class T>
class B : public A {
    ...
public:
    ...
    void foo();
    ...
};
void B::foo() {
    ...
}
template <>
void B<A>::foo() {
    ...
}
class C : A {
    ...
public:
    ...
    void foo();
    ...
};
int main() {
    B<C> bar;  // I was like "this is gonna work!! :) :D"
    bar.foo(); // But this calls B::foo() instead of B<A>::foo()... :'( *sob*
}

还有一个例子:

// This example doesn't work because B ends up being abstract
class A {
public:
    virtual void foo() = 0;
};
template <class T>
class B : public A {
    ...
public:
    ...
    template <class U=T>
    typename std::enable_if<!std::is_base_of<U, A>::value, void>::type
    foo() {
        ...
    }
    template <class U=T>
    typename std::enable_if<std::is_base_of<U, A>::value, void>::type
    foo() {
        ...
    }
};
class C : A {
    ...
public:
    ...
    void foo();
    ...
};
int main() {
              // I got excited thinking this would work (^.^)/
    B<C> bar; // and then it didn't because B is abstract /(-_-) ...
    bar.foo();
}

对于如何解决这个问题有什么想法吗?谢谢! !

B<C>B<A>是不同的类型,所以你的第一种情况永远不会起作用。

您要做的是专门化模板为std::is_base_of<A, T>::valuetrue的所有类T。为此,使用部分专门化的默认模板参数:

template <class T, bool = std::is_base_of<A, T>::value>
class B : public A {
public:
    void foo() override { std::cout << "A is not base of T!" << std::endl; }
};

template <class T>
class B<T, true> : public A {
public:
    void foo() override { std::cout << "A is base of T!" << std::endl; }
};

当A是T的基时,bool参数为true,因此使用部分专门化。否则,使用基本模板。

请注意,即使AT不可访问的基础,is_base_of也会返回true,因此您可能还需要添加is_convertible<T*, A*>检查。

演示。