源码中学模板技巧

  1. 使用SFINAE技术判断一个类是否无析构函数
template<typename T>
struct has_no_destroy
{
#ifdef __GXX_EXPERIMENTAL_CXX0X__
  template <typename C> static char test(decltype(&C::no_destroy));
#else
  template <typename C> static char test(typeof(&C::no_destroy));
#endif
  template <typename C> static int32_t test(...);
  const static bool value = sizeof(test<T>(0)) == 1;
};

如果测试类型中存在no_destroy静态函数,则在模板匹配时,匹配返回值为char类型的函数,否则匹配可变参数、返回值为int32_t的函数。所以根据返回值类型的不同确定其实际匹配的函数版本。

  1. 模板函数的显式实例化(Explicit instantiation)和显式特化(Explicit specialization)
    对函数而言,存在显式实例化和显式实例化的差别,如下所示:
//普通模板定义
template <typename T>
void convert(T v)
{
    std::cout << "convert..." << std::endl;
}

//显式模板实例化
template void convert<double>(double)
//参数可推导,则可省略
template void convert(double);

//模板显式特化
template<>
void convert<int>(int v)
{

}

通常模板采用隐式实例化方式,即在使用模板函数时,实例化类型参数对应的模板。如果强制生成对应类型的实例化,则需要显式实例化。在模板匹配时,其优先级顺序为:

普通函数>显式特化>显式具体化>普通模板函数

猜你喜欢

转载自blog.csdn.net/u011388696/article/details/80875624