博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转]C++ 函数模板特化导致的多重定义链接错误
阅读量:5362 次
发布时间:2019-06-15

本文共 2145 字,大约阅读时间需要 7 分钟。

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

现象描述

有文件"header.h"

#ifndef HEADER  #define HEADER    template 
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
() { return 30; } #endif

  

"Source.cpp"

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

 "main.cpp"

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

  

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

1>------ Build started: Project: Win32Project1, Configuration: Debug Win32 ------  1>  AllocatorNew.cpp  1>Source.obj : error LNK2005: "unsigned int __cdecl size_rb_tree_node
(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 HEADER    template 
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
() { return 30; } #endif

  

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

#ifndef HEADER  #define HEADER    template 
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
() { return 30; } #endif

  

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

转载于:https://www.cnblogs.com/arsblog/p/4838043.html

你可能感兴趣的文章
windos系统定时执行批处理文件(bat文件)
查看>>
thinkphp如何实现伪静态
查看>>
BZOJ 1925: [Sdoi2010]地精部落( dp )
查看>>
c++中的string常用函数用法总结!
查看>>
Week03-面向对象入门
查看>>
一个控制台程序,模拟机器人对话
查看>>
Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(上篇——纯前端多页面)
查看>>
我的PHP学习之路
查看>>
【题解】luogu p2340 奶牛会展
查看>>
对PostgreSQL的 SPI_prepare 的理解。
查看>>
解决响应式布局下兼容性的问题
查看>>
使用DBCP连接池对连接进行管理
查看>>
【洛谷】【堆+模拟】P2278 操作系统
查看>>
hdu3307 欧拉函数
查看>>
Spring Bean InitializingBean和DisposableBean实例
查看>>
[容斥][dp][快速幂] Jzoj P5862 孤独
查看>>
软件开发工作模型
查看>>
Java基础之字符串匹配大全
查看>>
面向对象
查看>>
lintcode83- Single Number II- midium
查看>>