以下为个人推测。
对于一个普通的符号
f
,编译器对它做的事情如下:
(1)
编译时
:包含
f
的
定义(实现)
的源文件输送给编译器,编译器会编译相关代码并将结果打包到对应的
.o
里;
(2)
链接时
:当某处需要使用符号
f
,便
通过符号的声明寻找符号的实现
,如果没找到某个符号的实现,就被报
undefined
错误。
对于非模版的符号,编译器会如上正常执行。
但对于模板类和模板函数,由于它的符号是抽象的,如
f<T>(T)
和
A<T>::f()
中的
T
是未知的。
所以在
(1)
时
不会
把“
符号
”的实现打包到
.o
。
(2)
时,实例化模板时,编译器才会看到
具体
的符号,如
f<double>(double)
和
A<int>::f()
,但此时编译器需要知道符号的实现,因此会报
undefined
错误。
解决办法就是,把模板的定义和声明放在一个文件里。
template.h
#ifndef TEMPLATE_H
#define TEMPLATE_H
#include <iostream>
template <typename T>
void f(T);
template <typename T>
class A {
public:
void f();
template <typename T>
void f(T)
std::cout << "::f" << std::endl;
template <typename T>
void A<T>::f()
std::cout << "A::f" << std::endl;
#endif
测试代码:
main.cpp
#include "template.h"
int main()
f(3.14);
A<int> a;
a.f();
return 0;
运行结果:
由于声明和定义写在了一起,在实例化模板时,通过符号的声明就能找到它的实现,因此链接不会出错。
对于一个普通的符号f,编译器对它做的事情如下:(1)编译时:包含f的定义(实现) 的源文件输送给编译器,编译器会编译相关代码并将结果打包到对应的.o里;(2)链接时:当某处需要使用符号f,便通过符号的声明寻找符号的实现,如果没找到某个符号的实现,就被报undefined错误。对于非模版的符号,编译器会如上正常执行。但对于模板类和模板函数,由于它的符号是抽象的,如f<T>(T)和A<T>::f()中的T是未知的。所以在(1)时不会把“符号”的实现打包到.o。(2)时,实例化模板时,编译器才会看到
本文实例为大家分享了C++利用链表
模板类实现一个队列的具体代码,供大家参考,具体内容如下
设计思想:MyQueue.h中对
模板类进行
声明和实现。首先
定义结点的结构体,包含数据和指针域两部分。队列类
定义中
声明和实现了元素入队,出队,打印队首元素和队列等方法。
1)
模板类的
声明和
定义不能分开(即不能分别
放在.h和.cpp文件里)。
2)
声明新节点时,如果
声明的节点是辅助操作的,可以不用new关键字,例如在析构函数中,直接用:Node<T>* temp;
定义即可。如果
声明一个新节点加入队列,则要用new关键字,否则会报出nullptr异常。
ConsoleApplication.cpp
问题起因是我在一个.h文件中定义模版类,忘了在.cpp中定义函数时如何写(就是忘了 CLASS::show中的),然后顺便在.h中声明了个模板函数(函数原型),又在cpp中定义,结果在主函数中用时,出现错误(未定义)。于是搜索,原来总结一句话如下
模版函数在.h中必须定义声明一块,都在其中。不能像普通函数一样,一个.h一个cpp,同样模板类的函数也不行,只是它可以在类中先声明,然后在类外
本文首发于我的公众号:码农手札,主要介绍linux下c++开发的知识包括网络编程的知识同时也会介绍一些有趣的算法题,欢迎大家关注,利用碎片时间学习一些编程知识,冰冻三尺非一日之寒,让我们
一起加油!
说实话,我个人是不怎么使用
模板的,使用场景很少,因此在上一篇博客里面难得用了一次
模板,反而出了点小问题,我遇到的问题就是把
声明和实现分开在h文件和cpp文件,因此在编译的时候怎么都无法通过,简直懵...
首先,C++标准中提到,一个编译单元[translation unit]是指一个.cpp文件以及它所include的所有.h文件,.h文件里的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个.obj文件,后者拥有PE[Portable Executable,即windows可执行文件]文件格式,并且本身包含的就已经是二进制码,但
当编译器将一个工程里的所有.cpp文件以...
首先明确的是:
对普通函数来说,声明放在头文件中,定义放在源文件中,其它的地方要使用该函数时,仅需要包含头文件即可,因为编译器编译时是以一个源文件作为单元编译的,当它遇到不在本文件中定义的函数时,若能够找到其声明,则会将此符号放在本编译单元的外部符号表中,链接的时候自然就可以找到该符号的定义了。
对于模板。先明确,模板函数是在编译器遇到使用模板的代码时才将模板函数实例化(之前只有函数的模板定义
写了3年多C++程序,很少用到模板,我靠,今天想试一下,照着别人的例子写,什么鬼,怎么都运行不过,仔细比对代码才发现,C++模板的声明与定义必须放到一个文件,.h或者.hpp, 真是颠覆我对C++编程的认知,什么坑爹的语法。网上找资料,看博客,看书,才知道必须这样写,太坑了。
例如我写的一个A 模板类,A.h文件:
#pragma once
#include &...
“通常情况下,你会在.h文件中声明函数和类,而将它们的定义放置在一个单独的.cpp文件中。但是在使用模板时,这种习惯性做法将变得不再有用,因为当实例化一个模板时,编译器必须看到模板确切的定义,而不仅仅是它的声明。因此,最好的办法就是将模板的声明和定义都放置在同一个.h文件中。这就是为什么所有的STL头文件都包含模板定义的原因。”[1]
"标准要求编译器在实例化模板时必须在上下文中可以查看到其
[/code]
2.->*取的是类成员指针,[参考](https://stackoverflow.com/questions/6586205/what-are-the-pointer-to-member-operators-and-in-c)
指向4:root -> left -> right -> value = 4,和模板函数的参数有关