C++语言模板的特例化编译为多重定义问题
Vivian 2018-06-04 来源 : 阅读 884 评论 0

摘要:本文主要向大家介绍了C++语言模板的特例化编译为多重定义问题,模板的特例化是C++新标准的一个特点,可以自定义某些模板的实现,比如在比较函数compare可以使用less标准库模板比较string、int、char、指针等类型,但如果有const char*类型且比较字符串的字典大小时,就与之前的比较方式不同了,希望对大家学习C++语言有所帮助。

    本文主要向大家介绍了C++语言模板的特例化编译为多重定义问题,模板的特例化是C++新标准的一个特点,可以自定义某些模板的实现,比如在比较函数compare可以使用less标准库模板比较string、int、char、指针等类型,但如果有const char*类型且比较字符串的字典大小时,就与之前的比较方式不同了,希望对大家学习C++语言有所帮助。

#ifndef A_H
#define A_H
 
#include 
#include 
using std::less;
template typename T>
int compare(const T v1,const T v2) 
{
     
    if (less()(v1,v2)) 
    {
        return -1;
    }
    else if (less()(v2,v1))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
 
 
template 
inline int compare(const char *const a,const char *const b) 
{
    return strcmp(a,b);
}
 
#endif 
 
 
#include "a.h"
using std::cout;
using std::endl;
 
int main()
{
    cout 
    cout "123","asd") 
    return 0;
}


    现在看上去没什么问题,并且只有这两个文件编译通过且正常运行,如果多了一个包含a.h的文件a.cpp:
#include "a.h"
    这里只有一句,但包含了a.h文件表示将其模板函数的定义包含,且特例化的函数类似一个普通函数,则a.cpp、main.cpp包含多个相同函数的定义,因此在链接时有重定义问题。
    解决方法:
    使用内联inline声明特例化的模板,则某些函数的定义可以在多个文件包含(一些函数的实现可能不支持内联): 

template 
inline int compare(const char *a,const char *b) 
{
    return strcmp(a,b);
}


    另外一个是使用一个文件包含该头文件,让所有链接的文件只有一个特例化定义
    第三个是定义普通同名函数,通过重载调用非模板函数(在参数匹配级别相同时,非模板重载函数优先调用)

// a.h
#ifndef A_H
#define A_H
 
#include 
#include 
using std::less;
template typename T>
int compare(const T v1,const T v2)
{
 
    if (less()(v1,v2))
    {
        return -1;
    }
    else if (less()(v2,v1))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
 
int compare(const char *a,const char *b) ;
 
// a.cpp
#include "a.h"
 
int compare(const char *a, const char *b)
{
    std::cout "const char*"
    return strcmp(a,b);
}
// main.cpp 相同


    如果有其他的方法请大家一起交流

之前遇到了一些关于模板特例化的问题,自己总结一下。
    模板的特例化是C++新标准的一个特点,可以自定义某些模板的实现,比如在比较函数compare可以使用less标准库模板比较string、int、char、指针等类型,但如果有const char*类型且比较字符串的字典大小时,就与之前的比较方式不同了:

#ifndef A_H
#define A_H
 
#include 
#include 
using std::less;
template typename T>
int compare(const T v1,const T v2) 
{
     
    if (less()(v1,v2)) 
    {
        return -1;
    }
    else if (less()(v2,v1))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
 
 
template 
inline int compare(const char *const a,const char *const b) 
{
    return strcmp(a,b);
}
 
#endif 
 
 
#include "a.h"
using std::cout;
using std::endl;
 
int main()
{
    cout 
    cout "123","asd") 
    return 0;
}


    现在看上去没什么问题,并且只有这两个文件编译通过且正常运行,如果多了一个包含a.h的文件a.cpp:

#include "a.h"
    这里只有一句,但包含了a.h文件表示将其模板函数的定义包含,且特例化的函数类似一个普通函数,则a.cpp、main.cpp包含多个相同函数的定义,因此在链接时有重定义问题。
    解决方法:
    使用内联inline声明特例化的模板,则某些函数的定义可以在多个文件包含(一些函数的实现可能不支持内联): 

template 
inline int compare(const char *a,const char *b) 
{
    return strcmp(a,b);
}


    另外一个是使用一个文件包含该头文件,让所有链接的文件只有一个特例化定义
    第三个是定义普通同名函数,通过重载调用非模板函数(在参数匹配级别相同时,非模板重载函数优先调用)

// a.h
#ifndef A_H
#define A_H
 
#include 
#include 
using std::less;
template typename T>
int compare(const T v1,const T v2)
{
 
    if (less()(v1,v2))
    {
        return -1;
    }
    else if (less()(v2,v1))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
 
int compare(const char *a,const char *b) ;
 
// a.cpp
#include "a.h"
 
int compare(const char *a, const char *b)
{
    std::cout "const char*"
    return strcmp(a,b);
}
// main.cpp 相同

以上就介绍了C/C+的相关知识,希望对C/C+有兴趣的朋友有所帮助。了解更多内容,请关注职坐标编程语言C/C+频道!

本文由 @Vivian 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程