2_4_4 类成员模板、类型模板

4_4_类成员模板函数.cpp

#include "hjcommon.hpp"
#include "4_4/Test.h"

using namespace std;
HJ_NS_USING

//extern template Test<int>; // vs2017编译器此方式能编译通过, Ubuntu 18 编译报错。
extern template void tempFunc(float a, float b); // 显式实例化与实例化声明对于函数模板,在Ubuntu 18 能成功编译,且运行正常。

HJ_NS_BEGIN

template<typename A>
class Demo
{
public:
	template<typename B, typename C> Demo(B b, C c);
	template<typename D> void func(D c) {} // 类的成员模板函数,注意:类的成员模板函数不能是虚函数,否则编译报错
};
template<typename A> // 成员模板函数实现处写法:先写模板类的模板,再写成员模板函数的模板
template<typename B, typename C> // 模板构造函数建议与声明写在一起,否则编译器可能会编译报错。 在Ubuntu 18 编译会报此构造函数未定义。。
Demo<A>::Demo(B b, C c)			 // 引申:所有类型的模板函数的声明与实现都建议写在同一个文件里,或者声明时就实现。
{
	cout << "Demo. b=" << b << ",c=" << c << endl;
}

// 我们知道:在代码中Demo<int> d;定义这么一句,就表示告诉编译器实例化一个 Demo<int> 类,而且每个cpp文件都是独立编译的。
// 当如果在有多cpp文件中都这么 Demo<int> d; 定义了的话,编译器会生成多份 Demo<int> 类,c++11中引入显式实例化与实例化声明解决此问题
//template Demo<int>; // 显式实例化类模板,只需要显式实例化一个。建议写在源文件开头的位置
//extern template Demo<int>; // 实例化声明类模板,供其他cpp文件中使用,表示此类在其他cpp中实例化过了,不要重复实例化。建议写在源文件开头的位置

//template<typename T>
//void tempFunc(T t1, T t2) { cout << "函数模板显式实例化与实例化声明. t1=" << t1 << ",t2=" << t2 << endl; }
//template void tempFunc(int a, int b); // 函数模板一样用此方式显式实例化与实例化声明
//extern template void tempFunc(int a, int b);

// 建议:不要使用显式实例化模板与实例化声明模板,不同编译器,不一定能正常编译通过

HJ_NS_END

int main_2_4_4(int argc, char *argv[])
{
	Demo<int> d(1, "d"); // 可以
//	Demo<int> d2<int, String>(1, ""); // 不可以
	d.func('c'); // 可以
	d.func<char>('c'); // 可以

	// 显式实例化模板与实例化声明模板 测试
	Test<int> test(1, "t");
	tempFunc(1.1f, 2.3f);

	// 建议:由于不同编译器的行为不同,显式实例化与实例化声明建议不要使用。

	return 0;
}

4_5_类型模板.cpp

#include "hjcommon.hpp"
#include <map>

using namespace std;
HJ_NS_USING

// 加入要实现一个功能: 定义一个key为string,value值为随意的map。 c++98实现(使用typedef):
template<typename V>
struct map_s_98 // c++98中必须使用一个类来包装
{
	typedef std::map<String, V> type; // 定义别名
};
// c++11实现(使用using定义模板类型):
template<typename V>
using map_s_11 = std::map<String, V>; // c++11使用using直接定义类型模板,using在定义别名的时候是包含了typedef所有功能的,功能比typedef更强大

template<typename T>
using FuncPoint = int(*)(T, T); // 使用using定义类型模板,也可以称为模板别名
static int add(int a, int b) { return a+b; }

int main_2_4_5(int argc, char *argv[])
{
	map_s_98<int>::type map1; // get
	map1.insert({"one", 1}); // 需要 {} 。。
	map_s_11<String> map2; // get
	map2.insert({"two", "2"});

	FuncPoint<int> fp = add;
	cout << fp(1, 3) << endl;

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值