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

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

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

现象描述

有文件"header.h"

#ifndef HEADER
#define HEADER

template <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 HEADER

template <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 HEADER

template <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属性。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值