具有抽象基类的子类的C++模板特化

kot*_*ota 1 c++ templates template-specialization enable-if c++11

假设我有一个纯粹的抽象基类.类模板实现此接口,并且是专用的.现在,我的问题是这个专业化应该能够处理专业化的子类.所以,我尝试了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*
}
Run Code Online (Sandbox Code Playgroud)

另一个例子:

// 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();
}
Run Code Online (Sandbox Code Playgroud)

关于如何解决这个问题的任何想法?谢谢!!

T.C*_*.C. 7

B<C>并且B<A>是不同的类型,所以你的第一个案例永远不会奏效.

什么,你想要做的是专门为所有类的模板T为其std::is_base_of<A, T>::valuetrue.为此,请使用具有部分特化的默认模板参数:

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; }
};
Run Code Online (Sandbox Code Playgroud)

当A是T的基数时,bool参数是true如此使用部分特化.否则,使用基本模板.

请注意即使是不可访问的基础is_base_of也会返回,因此您可能还想添加一个检查.trueATis_convertible<T*, A*>

演示.