当前位置: 首页 > 知识库问答 >
问题:

模板专门化不能用于派生类

牛骞仕
2023-03-14
class Base {};
class Derived : public Base {};

template<typename T>
void doSomething(T t) { cout << "All Types!" << endl; }

template<>
void doSomething(Base b) { cout << "Base!" << endl; }

int main() {
    Derived d;
    doSomething(d);       //prints "All Types!"

    return 0;
}

我有一个模板函数doSomething(T),它接受任何类型的参数…类型基类除外。

所以我把doSomething模板专门用于类型Base的参数,所以它做了一些不同的事情。

然而,当我将派生类传递给doSomething时,它会打印“所有类型!”,而我希望它打印“Base!”,因为派生类本质上也是一个基类。

如果我有:

template<typename T>
void doSomething(T t) { cout << "All Types!" << endl; }

void doSomething(Base b) { cout << "Base!" << endl; }    

然后doSomething(d)也会打印“所有类型!”而不是“base!”,因为Derived2对象将被简单地视为类型模板参数

共有1个答案

韩佐
2023-03-14

您可以使用std::enable_if:解决此问题:

#include <type_traits>
#include <iostream>

class Base {};
class Derived1 : public Base {};
class Derived2 : public Derived1 {};

template<typename T>
typename std::enable_if< ! std::is_base_of<Base, T>::value>::type
doSomething(const T&) { std::cout << "All Types!" << std::endl; }

template<typename T>
typename std::enable_if<std::is_base_of<Base, T>::value>::type
doSomething(const T&) { std::cout << "Base or Derived!" << std::endl; }

int main() {
    // All Types!
    doSomething(1);
    // Base or Derived!
    doSomething(Base());
    doSomething(Derived1());
    doSomething(Derived2());

    return 0;
}

注意:参数是const T&,但是使用T作为参数已经避免了前面提到的切片。

注意:typename std::enable_if ::value>::type 是返回类型,它是std::enable_if的第二个可选模板参数,默认为void。

 类似资料:
  • 这里有一个最小的例子来说明我遇到的问题。 模板成员显式专用于基类中的。模板的代码是显式生成的,并在成员中调用。 我发现的第一个问题是: 该错误是由于在main中调用造成的。可以通过调用来避免这种情况。为什么在的实例中显然是不可见的?

  • 还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案

  • 我有一个模板基类,其模板参数类型为bool。此基类的构造函数参数列表取决于模板参数是true还是false。我想从这个类派生另一个模板类,它的模板参数是任意类型的。我需要这个派生类根据该类型的特征调用该基类的正确构造函数。 下面的例子并不包罗万象。无论是否为整数,基类模板bool可以是任何类型trait。此外,传递给派生类的模板参数的类型可以是任何类型。

  • 但是指定它是,因此它不再是模板类。它是否可以像虚函数一样专门化或重写?

  • 在本文中,他们说(c)是(b)的显式专门化。我的疑问是,为什么我们不能说它是(a)的显式专门化?因为我们可以为任何特定类型专门化模板。所以,当专门化int*时,为什么他们说(c)显式专门化(b)。 任何评论都将有助于理解事情。

  • 我有一个通用算法,需要访问其模板类型的特征。有一个特征类可以专门用于提供这些特征。 在我的类中使用此算法时,我想将其与类中定义的私有类型一起使用。 然而,专门化只能发生在或全局范围内,而我的类是不可访问的。 是否有可能以某种方式专门化具有私有类型的模板,至少在可访问此类型的范围内? 也许可以将这个专门化声明为一个类?