转载请注明文章:C++ 函数模板特化导致的多重定义链接错误 出处:多客博图

标题说的可能不是很清楚,解释一下,函数模板,一般都是放在头文件里面,所以有些时候,我也会做一个特化,也放在这个头文件里面,当这个头文件出现多次的包含之后,就会出现链接多重定义的错误,先说一个例子,如下:

现象描述

有文件"header.h"

#ifndef HEADER
#define HEADERtemplate <class T>
size_t size_rb_tree_node()
{return 20; /*constant value for l r p pointer and (color & height) and void * value*/
}template <>
size_t size_rb_tree_node<void *>()
{return 30;
}#endif

"Source.cpp"

#include "Header.h"int count()
{int a = size_rb_tree_node<int>();return a;
}

"main.cpp"

#include "Header.h"using namespace std;int count();int main()
{int a = size_rb_tree_node<int>();a = size_rb_tree_node<void *>();
}

编译后,在链接的时候报错了:

1>------ Build started: Project: Win32Project1, Configuration: Debug Win32 ------
1>  AllocatorNew.cpp
1>Source.obj : error LNK2005: "unsigned int __cdecl size_rb_tree_node<void *>(void)" (??$size_rb_tree_node@PAX@@YAIXZ) already defined in AllocatorNew.obj
1>C:\Users\tianzuoz\Documents\Visual Studio 2012\Projects\Win32Project1\Debug\Win32Project1.exe : fatal error LNK1169: one or more multiply defined symbols found
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

其实原因很简单了,因为特化后的函数就是一个普通函数,这个和在一个头文件里面定义一个函数,然后多出include这个头文件一样的结果,都会导致多重定义。

解决方法

1、把特化的函数,添加inline标记,这样,编译器不会给这个函数生成一个函数符号,就当作是一个宏展开吧,不过,有些编译器不一定会inline的。行不行试试就知道了,如下:

#ifndef HEADER
#define HEADERtemplate <class T>
size_t size_rb_tree_node()
{return 20; /*constant value for l r p pointer and (color & height) and void * value*/
}template <>
inline size_t size_rb_tree_node<void *>()
{return 30;
}#endif

2、让这个函数成为文件域,也就是不参与全局link,也是可以的:

#ifndef HEADER
#define HEADERtemplate <class T>
size_t size_rb_tree_node()
{return 20; /*constant value for l r p pointer and (color & height) and void * value*/
}template <>
static size_t size_rb_tree_node<void *>()
{return 30;
}#endif

3、还有一个办法就是,把这个特化从头文件里面拿出去,放在需要的实现文件里面,再添加static属性。

C++ 函数模板特化导致的多重定义链接错误相关推荐

  1. C++ 实验2:函数重载、函数模板、简单类的定义和实现

    1.函数重载编程 编写重载函数add(),实现对int型,double型,Complex型数据的加法.在main()函数中定义不同类型 数据,调用测试. #include <iostream&g ...

  2. c 语言 模板函数,函数模板特化

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include using namespace std; template size_t bytes(T & ...

  3. C++模板(函数模板,类模板)的基本使用与非类型模板参数与模板的特化

    C++模板 模板初阶 泛型编程 函数模板 函数模板概念 函数模板格式 函数模板的原理 函数模板的实例化 隐式实例化 显式实例化:在函数名后的<>中指定模板参数的实际类型 模板参数的匹配原则 ...

  4. C++知识点62——模板实参推断与函数模板的特化

    一.函数指针与模板实参推断 可以用函数模板初始化一个函数指针或给一个函数指针赋值 示例 template <typename T> int comp(const T &a, con ...

  5. 深入理解c++中的函数模板

    非类型模板参数 模板参数分类类型形参与非类型形参. 类型形参:出现在模板参数列表中,跟在class或者typename之类的参数类型名称. 非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类 ...

  6. C++模板——模板特化、分离编译

    这里写目录标题 一.泛型编程与模板 二.函数模板 1.概念 2.原理 3.函数模板的实例化 3. 模板实现复数类的加法 4.模板参数的匹配原则 三.类模板 1.定义格式 用类模板实现顺序表 2.非类型 ...

  7. [C++再学习系列] 函数模板和类模板

    函数模板和类模板 C++ 提供类模板和函数模板.函数模板允许重载 ,而类模板不允许重载(类无重载概念).类模板可以进行全特化和偏特化,而函数模板仅能够全特化 .因此,写一个看似函数模板偏特化的函数模板 ...

  8. C++模板之隐式实例化、显示实例化、隐式调用、显示调用和模板特化详解

    模板的实例化指函数模板(类模板)生成模板函数(模板类)的过程.对于函数模板而言,模板实例化之后,会生成一个真正的函数.而类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调用时才会被初始 ...

  9. C++基础:模板,函数模板和类模板

    文章目录 1. 函数模板 2. 类模板 3. 模板特化 3.1 函数模板特化 3.2 类模板特化 4. 非类型模板参数 模板是允许函数或类通过泛性的形式表现或运行的特性 1. 函数模板 模板可以使函数 ...

最新文章

  1. 关于mac的一些常用操作记录
  2. python环境变量配置_Anaconda从下载到环境变量配置(windows)
  3. Java Stream流的概念
  4. MATLAB实战系列(二十九)-头脑风暴优化(BSO)算法求解旅行商问题(TSP)-交叉算子
  5. python pygame模块怎么写游戏_使用 Python 和 Pygame 模块构建一个游戏框架
  6. rhel7.4搭建Discuz
  7. 计网复习第三章part one
  8. C#/winform 腾讯QQ注册
  9. 面试问题记录1:IP子网规划
  10. NS2中认知无线电仿真
  11. C语言经典面试题100道(附完整答案)
  12. 台式计算机操作系统的安装,Win10X电脑操作系统可以装在台式机吗?
  13. python调用rf关键字_RobotFramework之关键字
  14. 手把手教你搭建SpringCloud项目(十)集成OpenFeign服务接口调用
  15. [Android系统原理及开发要点详解
  16. Verilog语言学习
  17. 为什么一些linux基础静态库(如libc.a)里面包含那么多目标文件.o呢? 为什么不将这些.o文件进行提前糅合呢?
  18. 常用Android代码
  19. python3爬虫系列16之多线程爬取汽车之家批量下载图片
  20. Hive启动报错 java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: java.lang

热门文章

  1. java单态模式_Java单态模式
  2. mybatis学习6复杂查询之一对多的处理
  3. android子view获取父布局,Android获取布局父ID(Android get layout parent id)
  4. 鸿蒙系统突破,华为解锁新成就!新系统用户突破1亿,鸿蒙系统也传来了新消息...
  5. 16.Hadoop架构再探讨第1部分
  6. 【C++】19. 深入 char * ,char ** ,char a[ ] ,char *a[] 内核
  7. Tomcat 部署项目的三种方法
  8. Java 面试知识点解析(五)——网络协议篇
  9. 【年度开源、工具合集】牛津计划,DMTK,Graph Engine…提高你的工作效率!
  10. 海明嵌入Hamming Embedding生成Binary Signature之matlab程序代码