C++模板 - value traits

本文探讨了C++中的value traits,它用于解决类型初始化问题,特别是在累加函数中。通过示例展示了如何使用value traits避免无法通过类型()初始化的问题,并讨论了在类型不支持在类内初始化时的解决方案,包括在类外初始化和使用静态成员函数。然而,这些方法都有其局限性,需要权衡选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面的文章使用了type traits,其实traits还有value traits。

再看一下累加函数:

template<typename T>
struct traits;

template<>
struct traits<char>
{
	typedef int AccuT;
};

template<>
struct traits<int>
{
	typedef int AccuT;
};

template<class T>
typename traits<T>::AccuT accum3(const T* ptr, int len)
{
	traits<T>::AccuT total = traits<T>::AccuT();

	for (int i = 0; i < len; i++)
	{
		total += *(ptr + i);
	}

	return total;
}

注意这行代码:

traits<T>::AccuT total = traits<T>::AccuT();

如果AccuT是int,float等类型,那么int(), float()就会初始化成0,没有问题,那么万一对应的类型不可以()初始化呢?

这个时候就用到了value traits,可以把int traits改成:

template<>
struct traits<int>
{
	typedef int AccuT;
	static AccuT const Zero = 0;
};

这个traits里面有一个类型和一个值。

然后把累加函数改成:

template<class T>
typename traits<T>::AccuT accum3(const T* ptr, int len)
{
	traits<T>::AccuT total = traits<T>::Zero;

	for (int i = 0; i < len; i++)
	{
		total += *(ptr + i);
	}

	return total;
}

 这样就可以解决初始化问题了。然后就算有变动也只需要修改traits里面的Zero了。

 

但是这么做也有个问题,就是并不是所有的类型都可以在类里面初始化,比如,我们把int traits的返回值类型改成double:

template<>
struct traits<int>
{
	typedef double AccuT;
	static AccuT const Zero = 0;
};

这样编译器直接报错(vs2012),

error C2864: 'traits<int>::Zero' : only static const integral data members can be initialized within a class

有些人会在类外面来初始化这个值,比如:double const traits<int>::Zero = 0; 这也是个办法。但是感觉这不是个好办法。更一般的是在traits内部搞个静态函数,然后累加函数里面调用函数而不是静态变量。代码:

template<typename T>
struct traits;

template<>
struct traits<char>
{
	typedef int AccuT;
	static AccuT const Zero = 0;
};

template<>
struct traits<int>
{
	typedef double AccuT;
	static AccuT Zero(){ return 0.0; };
};

template<class T>
typename traits<T>::AccuT accum3(const T* ptr, int len)
{
	traits<T>::AccuT total = traits<T>::Zero();

	for (int i = 0; i < len; i++)
	{
		total += *(ptr + i);
	}

	return total;
}


int _tmain(int argc, _TCHAR* argv[])
{
	int sz[] = {1, 2, 3};
	traits<int>::AccuT avg = accum3(sz, 3) / 3;

	return 0;
}


 

 


 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值