C++模板坑,一起来issue

C++模板坑,一起来issue

C++开发中通常将类定义放在C ++头文件(.h)中,并将实现放在C ++源文件(.cpp)中。然后,将源文件作为项目的一部分,这意味着将其单独编译。但是,当我们对模板类实施此过程时,将出现一些编译和链接问题。

本文阐述了三种可能的解决方案,帮助大家可以在实现该模板的源文件中创建一个模板类的对象,解决上述问题。

问题复现

头文件声明:

// temp.h
#ifndef _TEMP_H_
#define _TEMP_H_
#include <iostream>
#include <vector>
template <typename T>
using Vec = std::vector<T>;
#define PRINTFMT(x) std::cout << x << " ";

template <typename T>
void TestTemp(const Vec<T> &v, T target);
#endif

头文件实现:

#include "temp.h"


template <typename T>
void TestTemp(const Vec<T> &v, T target)
{
    [=]() {
        for (auto elem : v)
            if (elem == target)
                PRINTFMT(elem);
    }();
}

报错:

undefined reference to....

问题描述:当在.h中声明了模板,.cpp中定义了模板,当main函数去进行模板实例化的时候,在声明处找不到对应的T类型,自然就出问题了。

1.第一种:同一文件

声明及定义都在.h文件中。

// temp.h
#ifndef _TEMP_H_
#define _TEMP_H_
#include <iostream>
#include <vector>
template <typename T>
using Vec = std::vector<T>;
#define PRINTFMT(x) std::cout << x << " ";

template <typename T>
void TestTemp(const Vec<T> &v, T target)
{
    [=]() {
        for (auto elem : v)
            if (elem == target)
                PRINTFMT(elem);
    }();
}
#endif

2.第二种:分离开+引入头文件

采用头文件声明,cpp定义,要想起作用,得在使用处引入两者并且定义处得用特化版本。

例如:

头文件实现:

// Temp.cpp
#include "temp.h"

void TestTemp(const Vec<int> &v, int target)
{
    [=]() {
        for (auto elem : v)
            if (elem == target)
                PRINTFMT(elem);
    }();
}

template <typename T>
void TestTemp(const Vec<T> &v, T target)
{
    [=]() {
        for (auto elem : v)
            if (elem == target)
                PRINTFMT(elem);
    }();
}

实现:

#include "temp.h"
#include "temp.cpp"

int main() {
    std::vector<int> v{1,2,3};
    int target = 2;
    TestTemp<int>(v,target);

    return 0;
}

3.在末尾引入cpp

只需要在.h头文件末尾引入cpp即可。

头文件只需要声明:

// temp.h
#ifndef _TEMP_H_
#define _TEMP_H_
#include <iostream>
#include <vector>
template <typename T>
using Vec = std::vector<T>;
#define PRINTFMT(x) std::cout << x << " ";

template <typename T>
void TestTemp(const Vec<T> &v, T target);
#include "temp.cpp"
#endif

头文件定义即可:

// Temp.cpp
#include "temp.h"

template <typename T>
void TestTemp(const Vec<T> &v, T target)
{
    [=]() {
        for (auto elem : v)
            if (elem == target)
                PRINTFMT(elem);
    }();
}

调用处正常调用:

#include "temp.h"

int main() {
    std::vector<int> v{1,2,3};
    int target = 2;
    TestTemp<int>(v,target);

    return 0;
}

在一些开源项目中,这种方式比较常见,只不过这里的.cpp得改为.hpp。其余不变!

4.总结

本节针对日常代码中的难点进行了梳理,提出了几种解决方案。可以简单的把模板理解为一种特殊的宏,模板类不要当作类,在被实例化的时候一定得找到定义,不然只看到声明,就GG了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值