15.4 成员函数模板,模板显式实例化与声明

15.4 成员函数模板,模板显式实例化与声明,第1张

一:普通类的成员函数模板

不管是普通类还是类模板,它的成员函数都可以是个函数模板,成为"成员函数模板",不可以是虚函数,否则编译器会报错。

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,还是能运行,很奇怪啊,很奇怪。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1295307.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存