栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

模板与泛型编程之值萃取

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

模板与泛型编程之值萃取

之前在说固定萃取的时候说过如下的例子:

template
struct TraitsType;

template<>
struct TraitsType
{
	using RetType = int;
};

template<>
struct TraitsType
{
	using RetType = __int64;
};


template
auto GetSum(T* begin, T* end)
{
	using retType = typename TraitsType::RetType;
	cout << typeid(T).name() <<"==>"<< typeid(retType).name() << endl;
	retType sum{};
	for (;;)
	{
		sum += (*begin);
		if (begin == end)
		{
			break;
		}
		begin++;
	}

	return sum;

}

int main()
{
	int a1[] = { 1,3,5,7 };
	int a2[] = { 500000000,500000000,700000000 };
	char a3[] = "abc";

	cout << GetSum(&a1[0], &a1[3]) << endl;
	cout << GetSum(&a2[0], &a2[2]) << endl;

	int nsum = (int)GetSum(&a3[0],&a3[2]);
	cout << nsum << endl;
	
	system("pause");
	return 0;
}

可以看到,求和的数组元素分别是int类型和char类型,其中char类型数据可以来看作范围比较窄的int类型数据,所以这两种类型数据都可以用RetType sum{};的形式进行零初始化,但如果数据组元素是其他类型的数据(如一个类类型),那么这种零初始化的格式可能就不合适。所以可以利用萃取技术解决这个问题,在说固定萃取的时候,核心思想是“传入一种类型,萃取出另外一种类型”,那么此处的值萃取的核心思想是“传入一种类型,萃取出一个值”。
将上面的代码修改为值萃取:

template
struct TraitsType;

template<>
struct TraitsType
{
	using RetType = int;
	static const RetType InitValue = 0;
};



template<>
struct TraitsType
{
	using RetType = __int64;
	static const RetType InitValue = 0;
};


template
auto GetSum(T* begin, T* end)
{
	using retType = typename TraitsType::RetType;
	cout << typeid(T).name() << "==>" << typeid(retType).name() << endl;
	retType sum = TraitsType::InitValue;
	for (;;)
	{
		sum += (*begin);
		if (begin == end)
		{
			break;
		}
		begin++;
	}

	return sum;

}

虽然这种写法目前看不出问题,达式如果对一个元素类型为double的数组求和,就会出现问题,如下增加一个类模板的特化。

template<>
struct TraitsType
{
	using RetType = double;
	static const RetType InitValue = 0.0;
};

结果编译报错:

看上面的报错提示,只有整型才能这样初始化,浮点数不可以,但是使用c++11标准引入的constexpr关键字,发现是可以的,所以如下修改。

template<>
struct TraitsType
{
	using RetType = double;
	static constexpr RetType InitValue = 0.0;
};

结果一切正常,可以看到,通过值萃取类模板的手段,分别解决了数组元素为int、char、double时的求和问题,但是如果数组元素时类类型,如何进行类类型的求和呢?

class A
{
public:
	A(int v1) :m_i(v1){}
	int m_i;

	A& operator+=(const A &obj)
	{
		m_i += obj.m_i;
		return *this;
	}
};

可以先做如下的尝试

template<>
struct TraitsType
{
	using RetType = A;
	static const RetType InitValue{0};
};

结果:

于是如下修改

template<>
struct TraitsType
{
	using RetType = A;
	static const RetType InitValue;//声明
};
const A TraitsType::InitValue = A{ 0 };//定义

最终解决问题,但是这种方式比较繁琐,在c++17中国,提出了一种新的解决方案解决类似的问题—inline变量,做如下修改:

template<>
struct TraitsType
{
	using RetType = A;
	inline static const RetType InitValue{0};//声明
};

先修改main:

int main()
{
	A a1[] = { A{1},A{3},A{5},A{7} };	
	cout << GetSum(&a1[0], &a1[3]).m_i << endl;
	system("pause");
	return 0;
}

结果:

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号