• [转]关于模板函数/模板类编译成DLL


    要编译成DLL,就要声明和实现分开。

    首先文件组织是这样的(为了简化,没有加上编译成DLL的语句)
    在 T.h 中(声明模板函数)
    template<typename T>
    T Max(T& t1,T& t2);
    在 T.cpp 中(模板函数的实现)
    #include"T.h"
    template<typename T>
    T Max(T& t1,T& t2)
    {
      return t1>t2?t1:t2;
    }
    编译 T.cpp 很好,通过编译
    在 Main.cpp 中(用于测试的)
    #include<iostream>
    using namespace std;
    #include"T.h"
    int main()
    {
      int a=3,b=4;
      cout<<Max(a,b)<<endl;
      double c=5.6,d=4.8;
      cout<<Max(c,d)<<endl;
      system("pause");
      return 0;
    编译 Main.cpp 很好,也通过编译
    然后 链接运行程序
    此时,产生链接错误了(Visual Studio 2008环境下)
    1>Main.obj : error LNK2019: 无法解析的外部符号 "double __cdecl Max<double>(double &,double &)" (??$Max@N@@YANAAN0@Z),该符号在函数 _main 中被引用
    1>Main.obj : error LNK2019: 无法解析的外部符号 "int __cdecl Max<int>(int &,int &)" (??$Max@H@@YAHAAH0@Z),该符号在函数 _main 中被引用
    链接器根本没有找到那两个函数
    发现模板的东西分开成 .h 和 .cpp 是不行的
    因为模板是需要在编译时实现特例化的,光编译T.cpp是没有产生可用的函数的。
    因此,模板函数/模板类也无法编译成DLL
    Visual Studio 中的系统库中的STL(标准模板库)都是以源代码的形式呈现的(例如<map>里面可以看到源码的)
    看来微软也没得好办法解决这个
    所以一般而言 模板的东西 还是都直接写到 .h 就好了
    至于说一定要分开成 .h 和 .cpp的话,用的时候需要#include".cpp"(这个方法很畸形,本质还是直接include了声明和实现,据说gcc可以分开成 .h 和 .cpp,没有测试过,应该只是编译器自动化的帮你include了)
    当然这样还是不能编译成DLL的,我查阅了一下,实在想编译成DLL的话,必须在编译模板的时候就进行特例化(其实这样失去了模板的优势了,唯一好点的就是可以特例化多种形式)
    在 原来的 T.cpp 中加上这段就可以特例化了(也可以加到 T.h 中)
    template int Max<int>(int& ,int& ); //int特例化
    template double Max<double>(double& ,double& ); //double特例化
    这样编译链接运行,就可以了
    要编译成DLL的话,加上DLL的那个关键字就可以了
    #ifdef DLL_EXPORTS
    #define DLLT_API __declspec(dllexport)
    #else
    #define DLL_API __declspec(dllimport)
    #endif

    C++现在这种编译时的模板化机制,岂不是让别个通用模板函数库的开发商只能开源了?
  • 相关阅读:
    hashmap的一些基础原理
    关于uuid
    读锁跟写锁的区别
    栈为什么效率比堆高
    MySQL行级锁、表级锁、页级锁详细介绍
    MYSQL MyISAM与InnoDB对比
    MYSQL锁表问题解决
    mysql查询锁表语句
    三种排序方法
    正则表达式
  • 原文地址:https://www.cnblogs.com/wxxweb/p/2140108.html
Copyright © 2020-2023  润新知