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对象将被简单地视为类型模板参数
您可以使用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
是返回类型,它是std::enable_if的第二个可选模板参数,默认为void。
这里有一个最小的例子来说明我遇到的问题。 模板成员显式专用于基类中的。模板的代码是显式生成的,并在成员中调用。 我发现的第一个问题是: 该错误是由于在main中调用造成的。可以通过调用来避免这种情况。为什么在的实例中显然是不可见的?
还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案
我有一个模板基类,其模板参数类型为bool。此基类的构造函数参数列表取决于模板参数是true还是false。我想从这个类派生另一个模板类,它的模板参数是任意类型的。我需要这个派生类根据该类型的特征调用该基类的正确构造函数。 下面的例子并不包罗万象。无论是否为整数,基类模板bool可以是任何类型trait。此外,传递给派生类的模板参数的类型可以是任何类型。
但是指定它是,因此它不再是模板类。它是否可以像虚函数一样专门化或重写?
在本文中,他们说(c)是(b)的显式专门化。我的疑问是,为什么我们不能说它是(a)的显式专门化?因为我们可以为任何特定类型专门化模板。所以,当专门化int*时,为什么他们说(c)显式专门化(b)。 任何评论都将有助于理解事情。
我有一个通用算法,需要访问其模板类型的特征。有一个特征类可以专门用于提供这些特征。 在我的类中使用此算法时,我想将其与类中定义的私有类型一起使用。 然而,专门化只能发生在或全局范围内,而我的类是不可访问的。 是否有可能以某种方式专门化具有私有类型的模板,至少在可访问此类型的范围内? 也许可以将这个专门化声明为一个类?