一:普通类的成员函数模板
不管是普通类还是类模板,它的成员函数都可以是个函数模板,成为"成员函数模板",不可以是虚函数,否则编译器会报错。
class A
{
public:
template<typename T1>
void myft(T1 tmpt)
{
cout << tmpt << endl;
}
};
int main()
{
A a;
a.myft(100); //编译器在遇到这条语句时,编译就会实例化这个函数模板。
return 0;
}
二:类模板的成员函数模板
类模板的模板参数必须用<>指定,成员函数模板(函数模板)的参数可以推断。
类模板的成员函数(包括普通成员函数 / 成员函数模板)只有为程序所用(代码中出现了对该函数或者该函数的模板调用时)的时候才会进行实例化。
如果某函数从未使用,则不会实例化该成员函数。
template<typename C>
class A
{
public:
void print()
{
cout << m_ic << endl;
}
template<typename T2>
A(T2 v1, T2 v2); //构造函数也引入自己的模板参数T2,和整个类的模板参数C没有关系
public:
C m_ic;
};
template<typename C>
template<typename T2>
A<C>::A(T2 v1, T2 v2)
{
m_ic = v1;
cout << v1 << " " << v2 << endl;
}
int main()
{
A<float> a1(1, 2); //实例化了一个A类,并用int类型来实例化构造函数
A<float> a2(1.1f, 2.2f); //A已经被上面代码进行实例化了,这里用float来实例化构造函数
a1.print();
a2.print();
return 0;
}
三:模板显式实例化与声明
为了防止在多个.cpp文件中都实例化相同的类模板,所以C++11提出了一种解决方法,我们称为"显式实例化"。
通过"显式实例化"来避免这种生成多个相同类模板实例的开销
A tmpobj(6, 7);
模板的实例定义只有一个,实例化声明可以有多个。
ca.h
#pragma once
#ifndef __CAH__
#define __CAH__
#include
using namespace std;
template<typename C>
class A
{
public:
template<typename T2>
A(T2 v1, T2 v2);
template<typename T1>
void myft(T1 tmpt)
{
cout << tmpt << endl;
}
public:
C m_ic;
};
template<typename C>
template<typename T2>
A<C>::A(T2 v1, T2 v2)
{
m_ic = (C)v1;
cout << v1 << " " << v2 << endl;
}
#endif // !__CAH__
test.cpp
#include
#include
#include "ca.h"
using namespace std;
extern template A<float>;
void mfunc()
{
A<float> a(1, 2);
};
MyProject.cpp
#include
#include
#include "ca.h"
using namespace std;
extern template A<float>;
int main()
{
A<float> a1(1, 2);
A<float> a2(1.1, 2.2);
a1.myft(3);
return 0;
}
显示实例化实例化声明
extern template A; //其他的所有.cpp文件中都这么写 extern:定义外部变量
extern template void myfunc(int v1, int v2);
extern作用:不会在文件中生成一个extern后面所表示的模板的实例化版本代码
extern目的:告诉编译器,其他的源文件(.cpp)中已经有了一个该模板的实例化版本了
总结
<1>vs2017不太推荐这个特色,因为该特色虽然有作用但也会把所有成员函数都实例化出来,增加了编译时间和代码长度。
<2>
template A;
extern template A;
ps:测试怎么都加了extern,还是能运行,很奇怪啊,很奇怪。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)