C++模板类声明与实现分离:为什么你的代码无法通过编译?

模板究竟为什么不支持分离编译呢?!!! 模板类究竟为什么不支持分离编译呢?!! 究竟是为什么呢!!! 阅读详情

第一章:C++模板类声明与实现分离的编译之谜

C++模板的实例化机制决定了其声明与实现无法像普通函数那样自然分离。当编译器遇到模板类的声明(如在头文件中)而未见其实现时,它无法生成具体类型的代码——因为模板本身不是真实类型,仅是编译期的“蓝图”。

为何不能简单拆分 .h 与 .cpp?

模板实例化发生在使用点(point of instantiation),而非定义点。若将模板实现置于独立的 .cpp 文件中,主调用文件在编译时仅看到声明,缺乏生成 T 特化版本所需的完整定义,从而导致链接错误(undefined reference)。

典型错误复现

// stack.h
template<typename T>
class Stack {
public:
    void push(const T& item);
    T pop();
private:
    std::vector<T> data;
};

// stack.cpp(错误做法)
#include "stack.h"
template<typename T>
void Stack<T>::push(const T& item) {
    data.push_back(item);
}
template<typename T>
T Stack<T>::pop() {
    T top = data.back();
    data.pop_back();
    return top;
}
上述代码在单独编译 stack.cpp 时不会报错,但链接阶段会因 Stack<int> 等特化体缺失而失败。

可行的解决方案

  • 将全部模板定义(含函数体)置于头文件中(最常用、最可靠)
  • 显式实例化:在 stack.cpp 中添加 template class Stack<int>; template class Stack<std::string>;,强制编译器生成对应特化体
  • 使用 export 关键字(C++98 曾引入,但因无主流编译器支持,已于 C++11 废弃)

不同方案对比

方案可维护性编译速度适用场景
全头文件实现高慢(头文件被多次包含并重复解析)通用库、小型项目
显式实例化中(需预知所有使用类型)快(仅实例化所需类型)封闭系统、已知类型集

第二章:模板机制的核心原理剖析

2.1 模板实例化时机与编译链接模型

C++模板并非在定义时立即生成代码,而是在被具体类型调用时才触发实例化。这一机制决定了模板代码的编译和链接行为与普通函数显著不同。
隐式实例化时机
当模板被特定类型使用时,编译器才会生成对应的实例。例如:

template
void print(T value) {
    std::cout << value << std::endl;
}

int main() {
    print(42);        // 实例化 print<int>
    print("hello");   // 实例化 print<const char*>
}
上述代码中,print 函数模板在 main 中被调用时才分别生成 print<int> 和 print<const char*> 的具体实现。
编译模型与链接处理
由于模板定义需在每个使用它的编译单元中可见,通常将其实现放在头文件中。这避免了链接时“未定义引用”错误,但也可能导致代码膨胀。
  • 包含模型:模板声明与定义均在头文件
  • 显式实例化:在源文件中强制生成特定实例,控制代码生成位置

2.2 为什么普通类可以分离而模板不行

普通类的实现可以在头文件声明,源文件定义,编译器在链接阶段解析符号。但模板不同,它不是具体的类型,而是生成类型的“蓝图”。
编译机制差异
模板在实例化时才生成代码,编译器必须看到模板的完整定义。若实现分离在 `.cpp` 文件中,包含头文件的翻译单元无法生成具体实例。
  • 普通类:声明与定义可分离,链接器合并符号
  • 模板类:必须在头文件中提供完整定义
代码示例

// template.h
template<typename T>
class Stack {
public:
    void push(const T& item);
};

// 错误:push 实现在 .cpp 中,无法实例化
上述代码在其他文件包含 `template.h` 并使用 `Stack` 时,编译器无法找到 `push` 的定义,导致链接失败。必须将实现保留在头文件中。

2.3 隐式实例化与显式实例化的区别

在泛型编程中,隐式实例化和显式实例化决定了编译器如何生成模板的具体版本。
隐式实例化
当使用模板时未明确指定类型,编译器根据上下文自动推导并生成对应类型的实例。例如:

template
void print(T value) {
    std::cout << value << std::endl;
}

print(42);        // 隐式实例化:T 被推导为 int
此处 `print(42)` 触发编译器自动生成 `print`,无需手动声明。
显式实例化
程序员强制要求编译器为特定类型生成模板实例,常用于优化编译或提前捕获错误。

template void print(double);  // 显式实例化
该语句强制生成 `print` 的函数体,即使尚未调用。
  • 隐式实例化:延迟生成,依赖使用场景
  • 显式实例化:主动控制,提升编译可预测性

2.4 编译器视角下的模板处理流程

在C++中,模板并非运行时机制,而是由编译器在编译期完成实例化的核心特性。编译器对模板的处理分为两个关键阶段:**解析(parsing)** 和 **实例化(instantiation)**。
模板的两阶段查找
编译器首先在模板定义时进行语法检查,但不解析依赖于模板参数的具体符号。真正的符号绑定发生在实例化时,这一机制称为“两阶段名称查找”。

template<typename T>
void process(T t) {
    func(t); // func 的查找延迟到实例化时
}
上述代码中,func(t) 的解析推迟至 T 确定时,由编译器根据实参类型查找匹配的函数。
实例化过程
当模板被调用时,编译器生成对应类型的特化版本。此过程包括:
  • 参数推导:从实参推断模板参数
  • 代码生成:为具体类型生成实际函数或类
  • 错误检测:在实例化阶段发现类型不匹配等问题

2.5 链接器为何找不到模板函数的定义

在C++中,模板函数的实例化发生在编译阶段,但其定义必须在调用点可见。若将模板函数声明放在头文件,而定义置于源文件(.cpp),会导致链接器无法找到具体实例。
典型错误示例
// math.h
template<typename T>
T add(T a, T b);

// math.cpp
template<typename T>
T add(T a, T b) {
    return a + b;
}
上述代码中,add 的定义在 math.cpp 中,但由于没有显式实例化,链接器无法生成对应符号。
解决方案
  • 将模板定义全部放入头文件,确保编译器在实例化时可见;
  • 或在源文件中显式实例化所需类型:template int add<int>(int, int);

第三章:常见的错误尝试与解决方案

3.1 将实现放入.cpp文件后的编译错误分析

将函数实现从头文件移至 `.cpp` 文件是C++项目组织的常见实践,但若处理不当,易引发链接错误。
典型链接错误示例
最常见的问题是 `undefined reference to` 错误,通常出现在函数声明在头文件中,但定义未被正确编译或链接时。
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
#endif

// math_utils.cpp
#include "math_utils.h"
int add(int a, int b) {
    return a + b;  // 实现
}
上述代码逻辑正确,但若构建系统未将 `math_utils.cpp` 加入编译单元,`add` 函数将无法生成目标文件,导致链接阶段失败。
常见原因与排查清单
  • 源文件未加入编译命令或构建系统(如Makefile、CMake)
  • 拼写错误导致头文件包含失败
  • 函数签名不一致,如参数类型或const修饰符差异

3.2 使用显式实例化解决链接问题的实践

在C++模板编程中,链接错误常因模板函数或类成员未被实例化而发生。显式实例化可提前告知编译器生成特定类型的模板代码,避免跨编译单元的符号缺失。
显式实例化的语法形式

template class std::vector<int>;
template void process<double>(double value);
第一行强制生成 std::vector<int> 的完整定义;第二行确保 process 函数针对 double 类型被实例化,链接时将保留对应符号。
典型应用场景
  • 大型项目中分离模板声明与实现文件(.tpp)
  • 共享库(shared library)导出模板实例
  • 减少编译时间,集中管理常用实例类型
通过在实现文件中添加显式实例化指令,可有效控制模板膨胀并消除因隐式实例化失败导致的链接错误。

3.3 包含实现文件(.tpp)方法的利弊权衡

设计动机与典型结构
模板定义与实现分离是C++常见实践,但将实现置于独立的 .tpp 文件(而非头文件内联或分离的 .cpp)可兼顾编译速度与代码组织。典型用法是在头文件末尾显式包含:
// vector.h
template<typename T>
class Vector {
public:
    void push_back(const T& x);
};
#include "vector.tpp"  // 显式包含实现
该写法避免了隐式依赖,使构建系统能感知依赖关系,同时保留模板实例化所需的完整可见性。
关键权衡对比
维度优势风险
编译模型头文件更轻量,.tpp 可被多头复用易误删 #include "xxx.tpp" 导致链接错误
IDE支持跳转到定义仍指向头文件,语义一致部分静态分析工具不识别 .tpp 后缀,缺失语法检查

第四章:现代C++中的最佳实践模式

4.1 推荐的头文件内联实现结构设计

在C++开发中,头文件的内联函数设计需兼顾可读性与编译效率。推荐将声明与定义分离,但允许`inline`函数在头文件中实现。
内联函数的合理布局
为避免多重包含问题,应使用包含守卫,并将小型辅助函数标记为`inline`:

#ifndef UTILITY_H
#define UTILITY_H

inline int add(int a, int b) {
    return a + b;  // 编译器自动内联优化
}

#endif
该代码通过`inline`提示编译器进行内联展开,减少函数调用开销。`add`函数定义在头文件中,可在多个翻译单元安全使用而不会违反ODR(单一定义规则)。
适用场景与限制
  • 适用于短小、频繁调用的工具函数
  • 不建议在内联函数中包含复杂逻辑或大量局部变量
  • 模板函数天然适合头文件内联实现

4.2 使用模块(Modules)避免重复定义问题

在大型项目中,重复定义常导致命名冲突与维护困难。Go 模块通过封装和显式导出来解决这一问题。
模块的基本结构
package utils

func Add(a, b int) int {
    return a + b
}
该代码定义了一个名为 utils 的模块,仅导出 Add 函数(首字母大写),私有函数如 addHelper 不会被外部访问。
依赖管理与版本控制
使用 go.mod 文件声明模块路径与依赖版本:
module myproject/v2

go 1.21

require (
    github.com/sirupsen/logrus v1.9.0
)
此机制确保不同项目可依赖同一包的不同版本,避免“依赖地狱”。
  • 模块隔离命名空间,防止函数名冲突
  • 通过语义化版本控制提升可维护性
  • 支持私有仓库与本地替换(replace)指令

4.3 分离接口与实现的工程化组织策略

在大型软件系统中,将接口与实现解耦是提升模块可维护性与测试性的关键实践。通过定义清晰的抽象边界,不同团队可在统一契约下并行开发。
接口定义示例(Go)
type PaymentGateway interface {
    Process(amount float64) error
    Refund(txID string, amount float64) error
}
该接口约束了支付网关的行为,具体实现如AlipayGateway或PaypalGateway可独立演进,无需修改调用方代码。
工程化优势
  • 支持多团队协作:前端依赖接口,后端专注实现
  • 便于单元测试:可通过模拟接口隔离外部依赖
  • 实现热插拔:运行时根据配置加载不同实现
目录结构建议
路径职责
/interfaces定义核心契约
/adapters/alipay第三方实现适配
/internal/service业务逻辑编排

4.4 兼顾封装性与编译效率的设计技巧

在大型项目中,良好的封装性常带来头文件依赖膨胀,进而影响编译效率。通过使用**Pimpl惯用法**(Pointer to Implementation),可有效解耦接口与实现。
Pimpl减少编译依赖
class Widget {
private:
    class Impl;           // 前向声明
    std::unique_ptr<Impl> pImpl;
public:
    Widget();
    ~Widget();
    void doWork();
};
上述代码中,Impl 类的具体定义被移至实现文件,避免了包含大量头文件。即使修改实现,也不会触发接口文件重编译。
性能与维护的权衡
  • 降低模块间耦合度,提升并行开发效率
  • 增加一次指针解引用,轻微影响运行时性能
  • 适用于频繁变更或高依赖模块
合理运用前置声明与智能指针,可在不牺牲封装性的前提下显著缩短构建时间。

第五章:总结与未来展望

云原生架构的持续演进
现代企业正加速向云原生转型,Kubernetes 已成为容器编排的事实标准。以下是一个典型的 Helm Chart 部署示例,用于在生产环境中部署微服务:
apiVersion: v2
name: user-service
version: 1.0.0
appVersion: "1.5"
dependencies:
  - name: redis
    version: "12.10.0"
    repository: "https://charts.bitnami.com/bitnami"
该配置确保缓存层与业务逻辑解耦,提升系统可维护性。
AI 驱动的运维自动化
AIOps 正在重塑 DevOps 实践。通过机器学习模型分析日志流,可实现异常自动检测与根因定位。某金融客户采用 Prometheus + Grafana + Loki 栈,结合自定义告警规则,将平均故障恢复时间(MTTR)从 45 分钟降至 8 分钟。
  • 日志采集:Filebeat 收集容器日志并发送至 Kafka
  • 流处理:Flink 实时分析错误模式
  • 告警触发:基于动态阈值生成事件,推送至 PagerDuty
边缘计算与安全挑战
随着 IoT 设备激增,边缘节点的安全防护变得至关重要。以下是某智能制造场景中的安全加固策略对比:
措施实施方式效果
固件签名使用 RSA-2048 签名验证启动镜像防止恶意刷机
网络隔离通过 VLAN 划分设备通信域降低横向移动风险
未来,零信任架构将在边缘场景中进一步落地,结合硬件级可信执行环境(TEE),构建端到端安全闭环。
C++ 模板函数 讲解及实现 目录模板函数:机制介绍模板函数:实现代码 模板函数:机制介绍 在很多时候,我们需要对不同的数据类型做一些操作,但是这些操作是相同的,比如求取一个数组中的最大元素,我们只需: for(int i=0; i<arr.size(); i++) if(arr[i] > max_val) max_val = arr[i]; 可是面对不同的数据类型,我们需要实现不同的函数,比如下面我们需要实现两个函数来选择int或者double数组中的最大值,非常麻烦 int array_max(vector<i 阅读详情

相关推荐

细谈 C++ 类模板的分离式编译:类模板究竟要不要接口与实现分离

一、引言 只要是接触了 C++ 有一定时间的程序员,都会记住这么一个不成文的规定: 类模板的声明与实现最好放在同一个头文件中 这或许是来源于某次错误尝试的下意识的修改,又或许是简单搜索了下 C++ 类模板编译报错的原因,看到了满篇的诸如 “为什么 C++ 编译器不能支持对模板的分离式编译” 的博客,久而久之,就留下了这么一个印象。 那么实际上,如果你简单的记为 “C++ 编译器是不支持对模板的...

(ÒωÓױ) 1万+

模板类的声明和定义

模板的声明和定义

maple的博客 2269

C++中模板类的编译过程

首先要明白,C++中每一个对象所占的空间大小,对象的内存分布

u011201045的专栏 2372

C++模板的声明、实现和实例化

C++中,普通函数的声明和实现通常分别写在.h和.cpp中,但模板的声明和实现必须写在同一份文件中,否则编译会报错。

weixin_44514957的博客 555

C++模板类编译错误的定位与修复

在C++中,通常将模板类的声明放在头文件中,而实现放在源文件中。然而,这种分离方式可能导致编译错误。因为编译器在编译使用模板类的代码时,需要看到模板类的完整定义,如果实现部分没有被正确包含,编译器就无法生成相应的代码,从而报错。C++模板类编译错误的定位与修复需要开发者具备一定的C++语言基础和调试技巧。通过仔细阅读编译器错误信息、检查模板参数、统一模板声明与实现、处理依赖关系、检查命名空间以及使用静态断言和模板元编程技术等方法,可以有效地定位和修复模板类编译错误。

shejizuopin的博客 1618

C++类模板声明与实现分离

当模板声明与实现分离未处理得当时,会出现链接错误,如下: error LNK2019: unresolved external symbol poisson referenced 其实,LNK2019错误一般都是 compile是能找到相应的header (.h)文件,但链接时找不到相应的 lib 库文件(也含dll文件)。 首先,对编译器来说模板的声明与实现并不能真正的分离,我们要

Skyline 3640

模板类声明和定义为何要写一起

http://www.gois.ws/showfile.asp?id=460:0:0如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 PM 发表人: Nemanja Trifunovic 前言常遇到询问使用模板到底是否容易的问题,我的回答是:“模板的使用是容易的,但组织编写却不容易”。看看我们几乎每天都能遇到的模板类吧,如STL, ATL, WTL, 以及Boost的

~。~||| 1万+

为什么不能将类模板的声明与类模板函数实现分开写?

定义一个类一般都是在头文件中进行类声明,在cpp文件中实现,但使用模板时应注意目前的C++编译器还无法分离编译,最好将实现代码和声明代码均放在头 文件中。如: test.h template class CTest {   public:           T& GetValue();           void SetValue(const T& _Value);

h a 6 6 6 c k 为 你解决复杂难题! 2047

c/c++模板的定义和实现分开的问题及其解决方案

注意c/c++模板的定义和实现--定义一个类一般都是在头文件中进行类声明,在cpp文件中实现,但使用模板时应注意目前的C++编译器还无法分离编译,最好将实现代码和声明代码均放在头文件中。如:test.htemplate<classT>classCTest{public:T&GetVa...

weixin_30338743的博客 107

CAS5和CAS6自定义异常提示消息

CAS自定义异常提示消息

weixin_42949219的博客 979

用Python实现四叉树(quad tree)

import numpy as np #正方形类 class square: #lx、ly为左上角坐标(x对应行号,y对应列号),rx、ry为右下角坐标 def __init__(self,lx,ly,rx,ry): self.lx=lx self.ly=ly self.rx=rx self.ry=ry #检查该矩阵中是否满足条件 #参数:原矩阵,阈值 #返回值:布尔类型 def check(s

weixin_44164489的博客 5868

【C++】模板声明与定义不分离

一般在写C++相关代码的时候,我们总习惯于将类声明和类实现进行分离。也就是说,类的声明一般写在.h文件中,而它的实现一般写在.cpp文件中。但是,在模板类中,这个习惯却要恰恰相反。即:要求模板类的类声明和类实现要都放在头文件,而不能分离。 本文就对模板的这个奇特习惯进行分析。 本文实例源码github地址:https://github.com/yngzMiao/yngzmiao-blogs/tree/master/2020Q4/20201230。 分离式编译模式 在进行模板特性的讲解之前,首先需要了解一下

Yngz_Miao的博客 1万+

无人机测绘航线生成算法

JavaScript开发和测试无人机测绘航线的自动生成方法,设计可行,算法可靠

ly1302116的专栏 5235

C++模板类声明和定义几种写法

为什么模板类的实现放在cpp会出错 在编译用到了模板类的编译单元时,编译器需要访问方法或者类的实现,以实例化它们。 如果这些实现不在头文件中,则它们将不可访问,因此编译器将无法实例化模板,进而会导致编译出错。 模板类的定义必须放在.h文件中吗 答案是否定的,模板类的几种写法 声明和定义都放在.h中 // Foo.h template &amp;amp;amp;lt;typename T&amp;amp;amp;gt; struct Foo { ...

caikunbob的博客 2万+

王珊数据库系统概论第5版视频教材

目录 隐藏 说明:本课程共包括1种电子书、84个高清视频(共68课时)、1种纸质书(赠品)。 网授课程 王珊《数据库系统概论》(第5版)网授精讲班【共68课时】 序号 名称 课时 1 第1章 绪 论(1) 00:32:25 2 第1章 绪 论(2) 00:17:03 3 第1章 绪 论(3) 00:50:19 4 第1章 绪 论(4) 00:20:37 5 第1章 绪 论(5) 00:24:47 6 第2章 关系数据库(1) 00:47:23 7 第2章 关系数据库(2) 00:14:48 8 第2章 关系

mrtaoy96的博客 1147

保姆级教程:在ROS2 Humble上搞定Livox Mid-360雷达,从IP配置到Rviz点云显示

本文提供在ROS2 Humble上配置Livox Mid-360激光雷达的完整教程,涵盖从IP设置到Rviz点云显示的全流程。详细解析硬件连接、驱动编译、配置文件优化及常见问题排查,帮助开发者快速搭建开发环境并实现高效点云可视化。

weixin_30955617的博客 184

[C++]模板类的声明与实现分离问题

本文,记录C++模板类的实现。 目的:实现一个bag类 做法:模板类bag的声明与实现分离,也就是.cpp和.h文件分离 此时,编译失败。 将.cpp和.h取消(亦即取消声明与实现的分离) 此时,编译成功,运行正常。 马上查找资料,收集整理如下: C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译? ,链接Splitting temp

浪风一骑 5426

DSP篇--C6678功能调试系列之SPI调试

SPI传输数据分为线上直接收发和通过EDMA的数据传输两种。第一种是直接将数据放在线上(SPIDAT1),在寄存器(SPIBUF)中写入命令实现数据的收发;第二种需要配置EDMA,将数据buffer直接作为EDMA的数据源进行传输,其需要配置的参数和中断与EDMA一致。

nanke_yh的博客 1259

C++ 模板类的声明与实现分离问题(模板实例化)

c++在写模版函数时(template<class T>之类的),头文件不能与cpp文件分离。这就意味者,你头文件定义的含模版的地方必须在头文件中实现,没用模版定义的地方可以放在cpp中实现。 否则,将产生错误信息: 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 LNK2019 无法解析的外部符号 "public: void __thiscall XXX 有什么办法...

Jeff_的博客 4万+

Pyhon在振动信号处理中的高级应用(一):振动信号特征(时域、频域)提取

文章目录一、概述二、算法原理2.1 时域统计特征三、python代码实现 一、概述 二、算法原理   这里我们借鉴西安交通大学机械学院雷教授的论文《Fault diagnosis of rotating machinery based on multiple ANFIS combination with GAs》相关研究成果。雷教授在论文中共列举了4类共24种振动信号的时域和频域特征。 2.1 时域统计特征 p1=∑n=1Nx(n)NP2=∑n=1N(x(n)−p1)2N−1p3=(∑n=1N∣x(n)∣N

白银时代的博客 1万+

13、超声断层乳腺图像融合算法:乳腺癌诊断新突破

本文介绍了一种新型超声断层乳腺图像融合算法,通过结合超声透射(UTTc、UTTα)和反射断层图像(URT),实现对乳腺组织的多参数自动可视化。该算法能有效区分良性与恶性肿瘤,具有高准确性、无辐射、低成本等优势,适用于大规模乳腺癌早期筛查。初步临床测试验证了其可行性,未来有望成为乳腺癌诊断的新标准。

9q8w7e6r5的博客 155

C++模板类的声明与实现分离

1、我们在写类的时候一般通常将声明放到.h文件,函数实现放入.cpp,如下: //.h class Mystring{ public: Mystring(const char* str = "empty"); Mystring(const char* data, int len); ... ... ~Mystring(); int myRe...

only_a_Heroic_car的博客 1105

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

为什么模板的声明和实现不能分写在.h与.cpp中

《C++编程思想》第15章(第300页)说明了原因: 模板定义很特殊。由template<…>处理的任何东西都意味着编译器在当时不为它分配存储空间(没有具体的函数时不会对模板实例化),它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。 定义一个类一般都是在头文件中进行类声明,在cpp文件中实现,但使用模板时应注意目前的C++编译器还无法分离编译,最好将实现代码和声明...

寂蝶难双,窃窃思羽. 4741

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C++中模板类声明和实现能否分离?

1.声明部分 //point.h #ifndef _POINT_ #define _POINT_ template class Point { public: Point(Elem); } ; #endif 2.实现部分 //point.cpp #include "point.h" #include using namespace std; templ

yjw19901214的博客 2896

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

为什么模板类与模板成员函数不能分文件写(.h与.cpp)

定义一个类一般都是在头文件中进行类声明,在cpp文件中实现,但使用模板时应注意目前的C++编译器还无法分离编译,最好将实现代码和声明代码均放在头文件中。如: test.h template <class T> class CTest { public: T& GetValue(); void SetValue(const T...

u011846123的博客 3233

模板类的声明和定义中分离.h与.cpp

如果你用模板类的时候跟其它类一样把声明放在.h中那个,把定义放在.cpp中,是不是也出现了令人恼怒的 无法解析的外部符号 错误,在解决问题之前,请先看一下这篇关于编译原理的介绍,毕竟做学问要知其然更要知其所以然嘛~ http://www.doc88.com/p-841613271216.html 好啦,下面就是解决方法了: --------------------------------

Pandoras Box 1698
上一篇: Java时间戳陷阱揭秘:毫秒级获取为何在多线程下失效?
下一篇: PHP数组转JSON时中文变问号?5步精准定位并永久修复编码问题
VarFun
博客等级 码龄1年 151粉丝 1977原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值