【问题标题】:C++ Template specialization for subclasses with abstract base class具有抽象基类的子类的 C++ 模板特化
【发布时间】:2014-07-24 14:43:03
【问题描述】:

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

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

【问题讨论】:

  • 试试virtual void foo() = 0
  • @Ylisar 抱歉,这是示例中的一个错字。当然,如果它不是虚拟的,我会有其他问题。

标签: c++ templates c++11 template-specialization enable-if


【解决方案1】:

B&lt;C&gt;B&lt;A&gt; 是不同的类型,所以你的第一个案例永远不会工作。

您要做的是专门为 T 的所有类 std::is_base_of&lt;A, T&gt;::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; }
};

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

请注意,is_base_of 将返回 true,即使 AT 的不可访问基数,因此您可能还需要添加 is_convertible&lt;T*, A*&gt; 检查。

Demo.

【讨论】:

  • 也许这会更好地拆分成一个不同的问题,但假设 std::vector 也有一个特化。但我也想要一个专门化 U 何时是 A 的子类...我通过添加另一个参数来尝试它,默认情况下是 bool = false ,然后有一个 bool = std::is_base_of::再次有价值,但我无法让它工作......我在这里有一个example。有任何想法吗?另外,我在哪里可以了解您使用的部分专业化类型?我找不到任何东西...谢谢!
  • @kotakotakota 应该是一个单独的问题。
  • 其实,just got it。谢谢:)
  • @kotakotakota 我可能会用两个参数专门化 vector 品种以考虑自定义分配器,但其他方面做得很好:)
  • 哦,好主意。有人让我大开眼界this 解决方案,我认为这对这种情况也非常好。
猜你喜欢
  • 2021-12-12
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多