类模板相关知识

背景

之前的文章里我们分析过函数模板实例化的过程,可以参考这里,没搞明白的一定要搞清楚,不然后面越来越迷糊。现在类模板又是一种新的实例化流程,因为类模板有偏特化,所以和函数还不太一样。

流程

  • 首先实例化非偏特化模板,如果报错就截止,这里注意,因为类在编译的时候不会执行,所以只要模板参数个数对齐就可以
  • 上面没有报错的话,接着示例化各个偏特化模板,选着一个偏特化个数最多的模板作为最后的结果

demo

  • 报错
#include <iostream>
template<class T, class Enable >
class A {
 public:
  A() { std::cout << "primary template\r\n"; }
}; // primary template

template<class T>
class A<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
 public:
  A() { std::cout << "partial specialization\r\n"; }
}; // specialization for floating point types

int main() {
  A<double> a;
  }
//error: too few template arguments for class template 'A'

这里会报错,所以为了使用偏特化的功能,我们最好给Enable 改名给 dummy, 而且给一个默认赋值void, 不用担心和后面偏特化有竞争,即使一样编译器也会优先选择偏特化版本, 不会报错。

#include <iostream>
template<class T, class dummy = void>
class A {
 public:
  A() { std::cout << "primary template\r\n"; }
}; // primary template

template<class T>
class A<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
 public:
  A() { std::cout << "partial specialization\r\n"; }
}; // specialization for floating point types

/* First instantiated from: insights.cpp:47 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
class A<double, void>
{
  public: 
  inline A()
  {
    std::operator<<(std::cout, "partial specialization\r\n");
  }
};

int main() {
  A<double> a;
  }

可以看到,原模板也可以生成同样的实力,但是编译器优先选择符合的偏特化版本。

#include <iostream>
template<class T, class dummy = void >
class A {
 public:
  A() { std::cout << "primary template\r\n"; }
}; // primary template

template<class T>
class A<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
 public:
  A() { std::cout << "partial specialization\r\n"; }
}; // specialization for floating point types

template<class T>
class A<T, typename std::enable_if<std::is_same<T,double>::value>::type> {
 public:
  A() { std::cout << "second specialization\r\n"; }
}; // specialization for floating point types

int main() {
  A<double> a;
  }
 //ambiguous partial specializations of 'A<double>'

如果有两个一模一样的偏特化版本,那么就会编译报错。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值