C++模板 - value traits

前面的文章使用了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;
}
时间: 2024-11-12 09:27:36

C++模板 - value traits的相关文章

【C++模版之旅】项目中一次活用C++模板(traits)的经历

曾经曾在一个项目中碰到过一个挺简单的问题,但一时又不能用普通常规的方法去非常好的解决,最后通过C++模板的活用,通过traits相对照较巧妙的攻克了这个问题.本文主要想重现问题发生,若干解决方式的比較,以及最后怎样去解决的过程,或许终于的方案也并非最好的方案,但至少个人认为从发现到思考到解决到改善,这是一个对帮助个人成长非常不错的过程,所以凭记忆想把它记录下来,分享给大家. 先描写叙述下问题,项目中有这样一个接口类会暴露给外部使用,接口类定义例如以下(类方法名称以及描写叙述该问题无关的内容会有所

初识C++模板元编程(Template Mega Programming)

前言:毕设时在开源库上做的程序,但是源码看得很晕(当时导师告诉我这是模板元编程,可以不用太在乎),最近自己造轮子时想学习STL的源码,但也是一样的感觉,大致了解他这么做要干什么,但是不知道里面的机制.于是开始学习<C++模板元编程>,看完第二章对一些东西豁然开朗. PS:该书也有点老了,C++11标准还没出来,主要用的Boost库. Traits(特征) 说正题,在STL中经常可以见到后缀为traits的名字,比如经常用到的std::string,本质是类模板basic_string的第一个参

跨平台渲染框架尝试 - Texture管理

纹理是渲染器重要的资源,也是比较简单的资源.本文将详细讨论纹理资源的管理. 在资源管理概述中提到,资源就是一堆内存和CPU与GPU的访问权限.纹理管理在资源管理之上,要负责如何使用者一堆内存构造纹理对象,并告诉渲染器如何使用平台相关的纹理对象.下面,我们开始详细论述. 1. 纹理资源 首先纹理资源是GPU可以使用到的资源.它与Buffer资源不同的地方在于,相邻像素的插值计算中,纹理比Buffer简单并快得多,因为有相应的硬件实现.纹理资源字面意义上就像是一张像素图,但它不仅限于二维的像素的图,

Chromium和WebKit的智能指针实现原理分析

C++不像Java一样,由虚拟机负责对象分配和释放.也就是说,开发人员使用C++编写代码时,要自己负责对象分配和释放.WebKit和Chromium都是使用C++开发的,因此它们也面临上述问题.在解决对象释放问题时,要做到在对象不需要时自动释放,因为手动释放会带来忘记释放或者释放后又继续使用的隐患.智能指针是实现对象自动释放的有效技术手段.本文就分析Chromium和WebKit的智能指针的实现. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! 在现实中,

[转载] C++ 多线程编程总结

原文: http://www.cnblogs.com/zhiranok/archive/2012/05/13/cpp_multi_thread.html 在开发C++程序时,一般在吞吐量.并发.实时性上有较高的要求.设计C++程序时,总结起来可以从如下几点提高效率: l  并发 l  异步 l  缓存 下面将我平常工作中遇到一些问题例举一二,其设计思想无非以上三点. 1任务队列 1.1    以生产者-消费者模型设计任务队列 生产者-消费者模型是人们非常熟悉的模型,比如在某个服务器程序中,当Us

C++ 多线程编程总结

一.什么是多线程? 在计算机编程中,一个基本的概念就是同时对多个任务加以控制.许多程序设计问题都要求程序能够停下手头的工作,改为处理其他一些问题,再返回主进程.可以通过多种途径达到这个目的.最开始的时候,那些掌握机器低级语言的程序员编写一些"中断服务例程",主进程的暂停是通过硬件级的中断实现的.尽管这是一种有用的方法,但编出的程序很难移植,由此造成了另一类的代价高昂问题.中断对那些实时性很强的任务来说是很有必要的.但对于其他许多问题,只要求将问题划分进入独立运行的程序片断中,使整个程序

c++模板元编程七:类型判断的traits类

2 用于判断类型的traits类 is_void类可以判断模板参数的类型,使用很简单,注意,也可以直接使用::value. cout << std::is_void<void>::type::value << endl; cout << std::is_void<bool>::type::value << endl; 但是实现很有趣,特化居然可以用来继承不同的类.这里没有去找clang++实现代码,用boost代码代替吧. templ

模板:什么是Traits

Traits不是一种语法特性,而是一种模板编程技巧.Traits在C++标准库,尤其是STL中,有着不可替代的作用.   如何在编译期间区分类型   下面我们看一个实例,有四个类,Farm.Worker.Teacher和Doctor,我们需要区分他们是脑力劳动者还是体力劳动者.以便于做出不同的行动. 这里的问题在于,我们需要为两种类型提供一个统一的接口,但是对于不同的类型,必须做出不同的实现. 我们不希望写两个函数,然后让用户去区分. 于是我们借助了函数重载,在每个类的内部内置一个work_ty

【C++模版之旅】项目中一次活用C++模板(traits)的经历 -新注解

问题与需求: 请读者先看这篇文章,[C++模版之旅]项目中一次活用C++模板(traits)的经历. 对于此篇文章提出的问题,我给出一个新的思路. talking is cheap,show me the code. 代码: class ExportData { union { string * sp; long* lp; double* dp; void* vp; }; enum my_type {SP,LP,DP} types; static unordered_map<type_index