首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

是否允许使用隐式实例化而不是.H将类成员函数的C++模板定义放在CPP文件中?

在C++中,类的成员函数的模板定义通常需要放在头文件中,以便在使用时进行实例化。这是因为C++编译器需要在编译期间知道模板的定义,以生成相应的代码。

然而,C++也允许将模板的定义放在.cpp文件中,而不是头文件中。这种方式被称为隐式实例化(implicit instantiation)。隐式实例化的优势在于可以将模板的实现细节隐藏在.cpp文件中,只暴露出头文件中的接口,从而提高代码的封装性和可维护性。

使用隐式实例化时,需要在头文件中声明模板的存在,并提供模板的接口。然后在.cpp文件中包含头文件,并进行模板的实例化。这样,在使用模板的地方,编译器会根据需要自动实例化模板,并生成相应的代码。

然而,需要注意的是,隐式实例化可能会导致代码的可读性和可维护性降低。因为模板的定义被分散在不同的文件中,阅读代码时需要跳转到.cpp文件中查看模板的实现细节。此外,如果模板的定义发生变化,可能需要手动重新编译.cpp文件,而不仅仅是头文件。

总结起来,虽然C++允许使用隐式实例化将类成员函数的模板定义放在.cpp文件中,但这种做法可能会降低代码的可读性和可维护性。因此,建议将模板的定义放在头文件中,以便在使用时进行实例化。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++模板初阶&&STL简介

模板函数模板使用上有些区别,函数模板可以实例,通过实参类型进行函数推演,模板是无法实例,因为没有推演时机,所以对于模板,统一使用显示实例,即在后面加尖括号,尖括号存放类型名...说白了就是Stack.cpp里面的模板由于没有实例,那就是没有真正,所以成员函数地址无法进入符号表,那么在链接阶段,Test.cpp就无法链接到成员函数有效地址。 4....所以最好方式就是不要将成员函数定义和声明分文件存放,而是模板成员函数直接放在.h文件里面。...这样就不会出现找不到有效地址问题了,因为一旦Test.cpp中进行了模板实例,则.h文件那些方法也就会实例,此时他们地址就会进入符号表。...也有人会将.h文件重命名为.hpp文件,这就是典型模板声明和定义方式。

48610

c++模板编程解密:C++特化、实例和分离编译

类型形参即:出现在模板参数列表,跟在class或者typename之类参数类型名称 非类型形参,就是用一个常量作为(函数)模板一个参数,在(函数)模板可将该参数当成常量来使用 非类型模板参数允许一个值...这意味着你不能用动态计算值或者运行时才能得知值作为非类型模板参数实参 按需实例 按需实例,是 C++ 模板一个重要特性,指的是模板代码只有在真正被使用时才会被编译器实例C++ 模板本身并不直接生成可执行代码...这种生成过程只有在模板被用到时候才会发生,换言之,只有在代码地引用了模板具体实例,编译器才会根据模板生成那个特定实例代码。...源文件: .cpp 或 .cc 文件,包含定义在头文件声明过成员函数、全局变量定义等。...因此,最通用且常用方法是模板定义放在文件 前面我们知道,单个函数,进行定义分离没有错误,为什么模版不行呢? 单个函数(非模板函数)和模板在有很大不同,特别是在声明和定义分离。

36810

关于模板函数声明与定义问题

大家好,又见面了,我是你们朋友全栈君。 c++ primer上说:c++模板函数声明与定义通常放在文件普通函数通常是声明放在文件定义放在文件,为什么会有这样区别呢?...若将模板函数声明放在tem.h模板定义放在tem.cpp,在main.cpp包含头文件,调用add,按道理说应该实例int add(int,int)函数,即生成add函数相应代码,但是此时仅有声明...如果像上面那样使用模板,则只会在tem.cpp文件实例。 最后,对于模板来说,也同样符合上面的原则。...,因此在使用模板时候,首先会初始模板,同时初始模板相应构造函数使用模板实例调用相应成员函数时,才会初始模板成员函数。...如果类模板成员函数定义定义不在同一个编译单元(分离编译),此时调用成员函数便会出现未定义错误。当我们像代码那样在某个地方显调用它时就不会出现此类问题了。

2.2K30

C++打怪升级(八)- 泛型编程初见

函数模板实例 不同类型参数使用函数模板时,生成不同类型函数称为函数模板实例; 分为实例和显实例实例 由编译器在编译阶段根据我们所传实参推导函数模板参数实际类型然后生成某一具体类型函数...模板实例函数模板实例有些差别,模板实例必须在模板名字后跟,实例类型 ,注意模板名字不是真正实例结果才是真正(也就是模板名加上具体类型是真正名)...因为模板成员函数定义模板分离,test.cpp和class.cpp各自预处理/编译/汇编都是独立进行; test.c中有模板实例(我们显实例A),class.cpp没有模板实例...A,模板函数无法实例化成具体类型函数,class.o符号表也就没有具体函数地址; test.o虽有实例A,但是头文件class.h展开后,test.cpp只有模板函数声明,只实例化了函数声明...,而这又发生在链接阶段,导致链接错误; 解决方法 在函数定义文件主动显实例 这是一个不太好(实用)方法 既然链接错误是因为,模板成员函数只有声明显实例化了,那么我们也在模板成员函数定义文件内显实例即可

78520

C++模板总结

模板C++ 支持参数多态工具,使用模板可以使用户为或者函数声明一种一般模式,使得某些数据成员或者成员函数参数、返回值取得任意类型。...五、模板实例: 总结一下,C++ 只有模板实例 (explicit instantiation), 实例 (implicit instantiation) ,特化 (specialization...template void swap(T &a, T &b){ ... } 1、实例: 我们知道,模板函数不是真正函数定义,他只是如其名提供一个模板模板只有在运行时才会生成相应实例...,实例就是这种情况: [cpp] view plaincopyprint?...2、显实例: 前面已经提到实例可能影响效率,所以需要提高效率实例,显实例在编译期间就会生成实例,方法如下: [cpp] view plaincopyprint?

1.2K20

C++模板大总结!

模板C++支持参数多态工具,使用模板可以使用户为或者函数声明一种一般模式,使得某些数据成员或者成员函数参数、返回值取得任意类型。...五、模板实例: 总结一下,C++只有模板实例(explicit instantiation),实例(implicit instantiation),特化(specialization,...template void swap(T &a, T &b){ ... } 1、实例: 我们知道,模板函数不是真正函数定义,他只是如其名提供一个模板...,模板只有在运行时才会生成相应实例实例就是这种情况: [cpp] view plaincopyprint?...2、显实例: 前面已经提到实例可能影响效率,所以需要提高效率实例,显实例在编译期间就会生成实例,方法如下: [cpp] view plaincopyprint?

56520

C++】你想要——印刷模板

---- 2.模板 模板函数模板不同是:模板统一显实例,不需要推演,或者说没有推演时机,函数模板实参传递形参时,就会发生推演实例。...(个人习惯).h文件,我们写声明;.cpp文件,我们写定义;test.cpp,我们测试使用 但今天学习模板就不能这么做了!!...但在链接时候,test.cpp,却不能找到它地址,这是为什么??这就是模板和其他区别! 链接错误原因: .cpp定义不是实例模板,他只是一个模板,没有任何实例化成任何类型。...看上图:stack st; 显示实例,但是.h只有声明,test.cpp地方实例化了,但是定义地方stack.cpp却没有实例,只是一个模板。...方法二: 那就是模板编译不分离:(不要将定义和声明一个到.cpp,一个到.h) 当放在一个文件时,在编译时,.h 文件展开后,定义和声明都在test.cpp,那直接就会完成模板实例,就有了函数地址

39630

如何优雅传递 stl 容器作为函数参数来实现元素插入和遍历?

此时需要使用模板显示实例”在 engine_db.cpp 文件强制模板生成对应代码实体,来和 engine.cpp 调用点进行链接。..., map_inserter 放在文件中进行共享,类似于标准库头文件使用方式。...使用普通模板函数代替成员模板函数 本文最后,我们再回头看一下上面例子两个成员模板函数,发现它们并没有使用其它成员,其实完全可以将它们独立成两个普通模板函数去调用,例如改成这样: 1 namespace...C++函数模板编译方式 [5]. c++函数模板声明与定义相分离 [6]. C++模板函数模板实例和具体 [7]. C++ 函数模板 实例和具体 [8]. ...C++模板实例、显示实例调用、显示调用和模板特化详解 [9]. c++模板函数声明和定义分离 [10]. C++模板编程:如何使非通用模板函数实现声明和定义分离

3.6K20

C++函数模板模板

模板实例 实例化分为两种: **实例:**让编译器根据实参推演模板参数实际类型 如果遇到这种情况,模板只有一个参数,但是传参时候有连个不同类型怎么办?...(也就是模板过程是不可能实例,因为在创建一个模板时,最先调用时构造函数,但是构造函数不一定就要传参或者是模板参数类型,所以编译器无法推演,你直接告诉编译器把N都变成int类型就好了。...注意:这两个模板不是同一个类型。 因为里面的成员大小都不同了。...要注意,分离需要说明成员函数属于哪个类型,不是名,用模板说明类型就需要在名后面加 ,名+才是我们需要类型。...(函数定义地方才是放入符号表地址) 我们在创建实例化时,能实例只有声明,因为模板是一个蓝图,没有定义只有声明就无法实例,另一个源文件在有函数定义文件里又没有实例,所以就无法放入符号表

76800

C++】从零开始认识泛型编程 — 模版

比如:当用double类型使用函数模板时,编译器通过对实参类型推演,A确定为double类型,然 后产生一份专门处理double类型代码: 就这样编译器生成一个个函数模版实例,这是一种实例...我们在使用过程可以通过显示实例实例来进行实例: 显示实例:在函数名后中指定模板参数实际类型sum(a,b) ,直接表明想要进行什么数据类型函数即可。...模板函数允许自动类型转换,但普通函数可以进行自动类型转换 2 模板 什么是模版 模板(Class Templates):允许定义一个,其成员函数和方法可以操作任何类型数据。...因为 a.cpp函数定义没有实例,调用函数时仅仅是声明知道了使用什么模版类型,函数定义不知道使用什么模版参数,那自然无法实例!!!...解决方法很简单: 声明和定义放到一个文件 “xxx.hpp” 里面或者xxx.h就很好。推荐使用这种。因为.h文件预处理展开后,实例模版时,既有声明又有定义,直接就实例化了,就有函数地址了。

14910

不能定义声明dllimport_不允许 dllimport 静态数据成员

如果确实需要使用__declspec(dllimport),要注意VC规定: 数据、静态数据成员函数可以声明,但不能定义为 dllimport。 说白了就是,声明和定义分别放在.h及.cpp文件。...即__declspec(dllimport)声明放在.h文件,实现放在.cpp文件。 这样一处理,对于普通函数就可以使用方式2所谓‘导出’了。然而对模板却不行。...模板是需要‘具体,编译器直到碰到使用这个模板代码时候才会把模板编译成二进制代码。...留意一下STL代码你会发现,所有模板代码全 都放在一个.h文件,为什么不分开放在.cpp文件,因为放在.cpp文件即成为一个编译单元,一个单元就是一个PE结构,是实在二进制代码文 件,但这个单元没有调用这个模板又哪来编译单元...但如果我一定要使用SingletonDesign Pattern的话,那这个肯定是要有一个静态成员,每次LINK都没有,那不是完了?

1.8K20

C++系列(合集)】特性多又复杂?不存在!——这篇C++大全直接干碎(超级大全,精讲)

如果将其定义和声名分开,即放在.h文件定义函数放在.cpp文件函数不为内联函数。...模板参数实例化分为:实例和显实例实例实现任务是交给编译器。...1.实例 引入:实例机制是让编译器根据实参推演模板参数实际类型,而这往往会出现一些问题 适用情况:其交换两者是同一 不适用情况:其交换两者不是同一 template class 模板名 { // 成员定义 }; 二.模板实例 模板实例函数模板实例不同,模板实例需要在模板名字后跟,然后实例类型放在... 即可,模板名字不是真正实例结果才是真正

14710

C++编译与链接(0)-.h与.cpp定义与声明

C++中有的东西需要放在可以在.h文件定义,有的东西则必须放在.cpp文件定义,有的东西在不同cpp文件名字可以一样,而有的则不能一样 那么究竟哪些东西可在头文件定义,声明,哪些东西又必须在...(*C++11,标准允许使用等号=或者花括号{}进行就地非静态成员变量初始) 在内部定义成员函数将自动作为inline处理 在.h外部定义函数需要加上inline说明 否则在被include...模板函数模板声明与实现必须放在一个文件 总结 是否可以在.h定义 在不同.cpp是否可以重名 特殊说明 函数 不可以,会出现重定义错误 不可以 内联函数 可以 可以 为了确保所有调用该...所以static变量一般是放在.cpp出现并定义. static函数 可以 可以 是否可以在.h定义 是否可以就地初始 特殊说明 可以 数据成员 -----------------...需要到头文件以外去定义它) 静态常量整形数据成员 ------------------ 可以 特殊说明 模板 模板函数模板声明与实现必须放在一个文件 至于为什么会这样,与C++编译和链接

3.5K70

从零开始学C++模板(一):函数模板函数模板特化、重载函数模板、非模板函数重载

函数模板不是函数,不能被执行 置换代码类型参数得到模板函数——实例 实例模板函数是真正函数,可以被执行 3、模板被编译了两次 实例之前,先检查模板代码本身,查看语法是否正确;...4、普通函数只需要声明,即可顺利编译,模板编译需要查看模板定义(声明和定义放在同个.h文件) (三)、函数模板特化 假设现在我们有这样一个模板函数max: template <typename...const int&, const int&)     return 0; } 函数模板可以通过传递参数类型自动推导,查看是否有合适函数实例可用,模板则必须显说明模板类型参数,这样才能实例模板实例...四、模板偏特化 模板偏特化是指需要根据模板某些但不是全部参数进行特化 (1) 模板偏特化 例如c++标准库vector定义 template <class T, class ...C++标准委员会仍在对下一个版本是否允许函数模板偏特化进行讨论。 参考: C++ primer 第四版 Effective C++ 3rd C++编程规范

1.9K00

C++】初识模板,拿来吧你

文章目录 一、泛型编程 二、函数模板 1.函数模板概念 2.函数模板格式 3.函数模板原理 4 函数模板实例 1. 实例 2....显实例 5.模板参数匹配原则 三、模板 1 模板定义格式 2 模板实例 四、模板不支持分离编译(了解) 一、泛型编程 如何实现一个通用交换函数呢?...模板名 { // 成员定义 }; // 动态顺序表 // 注意:Vector不是具体,是编译器根据被实例类型生成具体模具 template class Vector...= _capacity = 0; } 2 模板实例 模板实例函数模板实例不同,模板实例需要在模板名字后跟,然后实例类型放在即可,模板名字不是真正实例结果才是真正...比较麻烦 法2.不分离定义到两个文件.h和.cpp,直接在同一个文件定义 这里我们先简单了解一下。

25730

两万字长文,见过最好模板元编程文章!

实例(implicit instantiation):当使用实例模板时自动地在当前代码单元之前插入模板实例代码,模板成员函数一直到引用时才被实例; 显实例(explicit instantiation...(详见文献[1] 1.3、文献[4]模板): 包含模板编译模式:编译器生成每个编译单元遇到所有的模板实例,并存放在相应目标文件;链接器合并等价模板实例,生成可执行文件,要求实例化时模板定义可见...extern 新用法),一般模板全部实现代码放在同一个头文件并在用到模板地方用 #include 包含头文件,以防止出现实例不一致(如下面紧接着例子); 实例,编译链接简单例子如下(参考了文献...用法类似,template 用于指明嵌套类型或函数模板; this 用于指定查找基成员(当基是依赖模板参数模板实例时,由于实例总是推迟,这时不依赖模板参数名字不在基查找,文献[1...实例结果是产生具体类型(模板)或函数函数模板),同一模板实参完全等价产生等价实例类型或函数模板一般在头文件定义,可能被包含多次,编译和链接时会消除等价模板实例; template、typename

1.2K10

C++模板进阶

---- 三、模板分离编译 阅读我博客同学会发现,自从学习了模板以后,凡是要用到模板我们成员函数声明和定义都是放在一起,或者是直接在给出函数定义不提供函数声明,比如我们模拟实现...在找出错误原因后有的同学可能会说,这简单,在 Stack.cpp 模板进行显实例即可,如下: //Stack.cpp 增加显实例代码 template class Stack;...那么我们又需要将 Stack.cpp 实例类型改为 double,也就是说,在同一份代码我们只能定义同一种类型对象,那么这样也就失去了模板原本意义了。...STL 容器) 2、模板函数声明和定义放到同一个文件 “xxx.hpp” (hpp:.h + .cpp) 。...(这种方式使用较大时,方便别人快速了解我们) 3、注:这两种方法都有一个缺点 – 会暴露源码,因为函数声明和定义是在一个文件,我们提供给别人使用时不得不将源码也暴露给别人,这也是模板一个缺点

41700

模版初阶

模板函数允许自动类型转换,但普通函数可以进行自动类型转换 在C++,当考虑函数重载和类型转换时,非模板函数相比模板函数有一个特点,即非模板函数可以利用C++类型转换规则(也称为标准转换序列),...具体来说: 非模板函数:如果有一个非模板函数,且传入实参类型可以通过转换匹配到该函数形参类型,那么这个转换会被自动应用,允许调用该函数。...如果直接调用模板函数并传入参数,编译器会严格检查参数类型是否可以直接匹配模板参数,不会自动进行如整型提升或用户定义转换等。...]; _capacity = capacity; _size = 0; } 在模板,当你在定义之外(外)声明或定义成员函数时,需要使用模板语法来指定模板参数,这是因为成员函数实际上是模板成员...模版实例 模板实例函数模板实例不同,模板实例需要在模板名字后跟,然后实例类型放在即可,模板名字不是真正实例结果才是真正 int main()

4200

【笔记】《深入理解C++11》(上)

初始列表效果总是慢于就地初始, 但也快过在构造函数中进行赋值 注意: 非常量静态变量依然要在头文件定义从而保证在程序只存在一个 sizeof()可以对成员表达式使用模板也可以声明友元了...原因和extern变量一样, 普通模板只存在于对应文件.o, 如果一个模板文件被多个文件实例就会产生多份重复代码, 没有extern的话此时重复模板会冲突....有了extern后编译器会自动删除重复实例模板, 不但节省内存还节省了多余实例化时间 注意被其他文件调用外部模板一定要在要用到实例之前实例 局部和匿名成员可以作为模板实参了, 但仍要注意匿名类型声明不能在参数位置..., 例如当存在非POD成员且这个成员有非平凡构造函数时, 这个union默认构造将被删除 匿名union对外是开放, 因此放在声明可以按照构造函数不同初始化为不同类型, 此时被称为枚举...而且由于其本质是常量数值原因, enum成员总是可以被转换为整型, 这很容易导致比较两个不同枚举名称时出现错误结果 C++11之前会通过结构枚举封装, 并建立新转换和比较函数覆盖原先操作

1.8K20

C++避坑指南

3.1 转换 C++定义类型在以下两种情况会发生转换: 1) 构造函数只有一个参数或除第一个参数外其他参数有默认值; 2) 实现了operator type()函数;...operator int()函数可以Integer类型转换为int。从下面代码和输出可以看出确实发生了类型转换。...D1模板参数并给m_value赋值,编译器提示无法int *转换成int类型,也就是m_value被实例化成了int不是int *。...D1查找T时,基B是非依赖型名称,无需知道模板实参就确定了T类型。 D2查找T时,基B是依赖型名称,在实例时候才会进行查找。...当希望安全this指针托管到shared_ptr时,目标对象需要继承std::enable_shared_from_this模板使用成员函数shared_from_this()来获得this

1.5K30
领券