CPP {模板类,类的全特化/偏特化}

CPP {模板类,类的全特化/偏特化}

模板类

错误

#模板类 声明和实现 必须放到头文件里#
a.h: template<T> struct ST{ void F();}, 然后你a.cpp: template<T> ST<T>::F(){ ...}
这是错误的, 到时候b.cpp里 是找不到的;
. 有个疑问: std::vector::emplate_back 他的实现放哪了?(因为他是动态库 所以情况不同?)

性质

template<?,?>裡面的constexpr(準確來說 必須是static constexpr)都是完全相同的!
.<int,1><char,2>constexpr常量 都是一樣的;
. 即 雖然模板類就是(代碼) 即好像同一個類 的不同模板 好像是很不同的, 但是 他們的constexpr都是一樣的;

<int,1><char,2>裡面的 static const常量 都是一樣的; 比如: template<class A, int B> class ST{ static const A M = B;}; 那麼<int,1>::M等於int 1, 而<char, 2::M等於char 2, 他們是不同的;

@DELI;

template< int A> ST;
类模板中的A, 且他必須是is_integral的, 即<bool/char/int... A>是可以的 但是<double A>是錯誤的;
他接收的實際參數 必須是constexpr的, 比如const int a1 = rand(); constexpr int a2 = 123; 那麼ST<a2>, ST<3>是可以的, 而ST<a1>是錯誤;

@DELI;

template< class A, int B>
class ST{
};
ST<int,123> x;

我们如何通过x对象 来获取其A|B的值呢(即int|123);

做法是:

template< class A, int B>
class ST{
    using AA = A;
    static constexpr int BB = B;
};

然后通过decltype(x)::AA/BB就可以获得int/123;

模板类的全特化/偏特化

算法

根据不同类型 执行不同函数

对于模板函数, 如果其模板参数为整型 就执行逻辑A, 否则执行逻辑B;
. 一个错误做法是: template<T> Func( T _t){ if( std::is_tegeral_v<T>){ A...} else{ B...} }; 因为比如A...里面有_t *= 2操作, 可是假如T==string 此时虽然不会进入A... 但编译器在编译期间 他可不知道 他还是会执行string *= 2 发现是未定义的 即编译错误;
. 再看一个错误做法: 把A...替换成Handle_integral()函数, 即把A..., B...代码逻辑 用单独的函数来替换; 你可能认为这样就能蒙混过关了, 其实也是错的… 因为他俩本质上是一样的! 即还是会调用Handle_integral( string) 依然是编译错误;
因此 基本上 永远不要在函数里 执行if( 编译期判断(诸如std::is_same_v) ){ ...}, 这是错误的, 因为类型是编译期 而函数是运行期;

正解是: 偏特化模板类; (可参考SUPIMO::toString的设计);

template< class _T, int8_t _Check> struct __work;
template< class _T> struct __work<_T, 0>{ // Integral
	static void Func( _T _t){ _t一定是整型}
};
template< class _T> struct __work<_T, 1>{ // Non-Integral
	static void Func( _T _t){ _t一定不是整型}
};
template< class _t> struct Work : __work<_t, (std::is_integral_v<_t> ? 0 : 1)>{};

调用: `T t;`  `Work<T>::Func( t);`
  • 16
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值