• C++模板


    最近使用了c++模板,觉得非常强大,只是写起来需要掌握一点技巧。大部分模板都是直接把定义写在.h头文件,并且有些人还说这样做的原因是模板不支持分编译,可是以前的编译器对模板的支持不够好吧,但是现在完全可以。

    环境:

    win7 32旗舰版、VS2010 sp1

    1、普通函数模板

    define.h文件

    1 template<typename T>
    2 T GetString(int value);

    define.cpp文件

     1 #include "define.h"
     2 
     3 template<typename T>
     4 T GetString<T>(int value)
     5 {
     6     return T(value);
     7 }
     8 
     9 //偏特化
    10 template<>
    11 string GetString<string>(int value)
    12 {
    13     char psz[32] = {0};
    14     itoa(value, psz, 10);
    15     return string(psz);
    16 }
    17 
    18 //偏特化
    19 template<>
    20 wstring GetString<wstring>(int value)
    21 {
    22     wchar_t psz[32] = {0};
    23     _itow(value, psz, 10);
    24     return wstring(psz);
    25 }
    如果我们直接包含define.h后,使用GetString<int>(100)函数调用,是使用不了的,会产生链接错误,为什么呢?我们上面定了函数模板的通用
    实现,但是并没有实例化为一个真正的函数,既然不是函数,编译器当然不会生成代码,所以会出现链接错误;要解决这个问题的最主要就是实例化函
    数模板使之成为一个真正的函数,第一种办法是:使用上面偏特化的方法,例如string和wstring类型的偏特化,因为上面已经写了,所以不多说了;
    下面说第二种办法:
    1 #define TEMPLATE_GET_STRING(T) template T GetString<T>(int value);
    2 TEMPLATE_GET_STRING(int)//函数模板实例化
    3 // 如果要在dll中导出此函数,我们可以这样
    4 template __declspec(dllexport) int GetString<int>(int value);

    2、类模板

    define.h文件

     1 template<typename T>
     2 class A
     3 {
     4 public:
     5     A()
     6     {
     7         InitValue();
     8     }
     9 
    10     void InitValue();
    11 
    12     int m_nValue;
    13 };

    define.cpp文件 

     1 template<typename T>
     2 A<T>::A()
     3 {
     4     InitValue();
     5 }
     6 
     7 template<>
     8 void A<string>::InitValue()
     9 {
    10     m_nValue = 100;
    11 }
    12 
    13 template<>
    14 void A<int>::InitValue()
    15 {
    16     m_nValue = 200;
    17 }
    18 
    19 // 类模板实例化
    20 template
    21 A<int>;

    3、成员函数模板

    define.h文件

    1 class B
    2 {
    3 public:
    4     template<typename T>
    5     T Get(int index);
    6 };

    define.cpp文件

     1 //成员函数模板偏特化
     2 template<>
     3 double B::Get<double>(int index)
     4 {
     5     return 2.1;
     6 }
     7 
     8 //成员函数模板偏特化
     9 template<>
    10 int B::Get<int><int>(int index)
    11 {
    12     return 1;
    13 }
    14 </int>
    15 //如果类B是一个数据库封装类,我们就可以利用这样的调用方式来获取数据库一条记录中的字段
    16 
    17 B b;
    18 b.Get<int>(1);//获取当前记录中第一个字段的值,并转化为int类型
    19 b.Get<double>(2)//获取当前记录中第二个字段的值,并转化为double类型
  • 相关阅读:
    EXT2
    Ext.DomQuery

    spring.net+nhibernate
    网址
    一句代码就解决一个开发中常见的小bug....
    Swift 已经正式开源了! 你了解到了吗?
    [知识点随笔] UIView--transform 属性
    懒加载(延迟加载)之后,在使用数据过程中容易出现的bug
    java设计模式
  • 原文地址:https://www.cnblogs.com/dongc/p/4893052.html
Copyright © 2020-2023  润新知