c++无类型参数模板(non-type template parameter)

无类型的模板参数:C++的template可以传入普通的参数,和平时使用普通的函数参数有点相似,但又有很大的不同。

这种形式的模板一般是用来初始化类的数组成员的大小例如下面有的代码:

template<int size>
class CTest
{
	int m_data[size];
};

void main()
{
	CTest<10> obj;// 将obj对象的成员 数值m_data大小初始为10 ,是不是很简单?
}

用整型来作为无类型模板参数使用起来确实easy,那么换其他类型试试?


收集了一点资料稍微整理了下,看看下面资料怎么说的:
a non-type template-parameter shall have one of the following types(无类型模板参数应该是下面所列举的类型):
1. integral or enumeration type(整型 或者 枚举)
2. pointer to object or pointer to function(对象的指针或函数指针,其实还包括基本类型的指针)
3. reference to object (对象的引用或者函数的引用)
4. Attention :The C++ standard does not allow floating point non-type template parameters
(注意:c++标准规定浮点型不能作为无类型模板的参数 例如 float,double,但他们的引用和指针是允许的。)



你已经知道了应该传入什么类型参数,说真的,这还远远不够。
a template-argument for a non-type, non-template template-parameter shall be one of:

1.对于整型参数:应该传入一个常量或者枚举值
an integral constant-expression of integral or enumeration type

2.对象的指针或者函数的地址因该具有外部连接属性,否则将报错;
— the address of an object or function with external linkage

3.可以是一个引用类型的参数参数 例如: template<int&> void func() {}; 
—the corresponding template-parameter is a reference


下面再来看看non-type template-parameter 有关的错误描述:
error c2970: 
an expression involving objects with internal linkage cannot be used as a non-type argument(涉及到对象内部连接的表达式不能作为 non-type argument)

error c2975:
expected compile-time constant expression(需要一个编译期常量表达式)

error c2971:
a local variable cannot be used as a non-type argument,You cannot use the name or address of a local variable as a template argument.(局部变量不能作为non-type argument,这里主要是指:指针和引用,但是局部整型常量除外,所以下面的代码是ok的。



下面是一些测试测试代码:

template<int>
void fun1()		{}
	
template<int*>
void fun1_1()	{}

template<int&>
void fun1_2()	{}

template<char*>
void fun2()		{}

template<char>
void fun3()		{}

struct	CA	{};
union	Ua	{};

// 浮点数 例如float,double,是不能作为 non-type template parameter的
//template<float>
//void fun4()	{}

// 要使用类的或者联合的指针 或者引用
//template<CA>			
//void fun4()	{}

//template<Ua>
//void fun5()	{}

template<CA*>			
void fun4_1()	{}

template<CA&>			
void fun4_2()	{}

template<Ua*>
void fun5_1()	{}

template<Ua&>
void fun5_2()	{}

//------------------------------------------------------------------------//
int			idata3 = 20;		// 外部链接
const int	idata2 = 9;			// 内部链接

CA			impCa1;				// 外部链接
const CA	impCa2;				// 内部链接
static CA	impCa3;				// 内部链接

Ua			impUa1;				// 外部链接
const Ua	impUa2;				// 内部链接
static Ua	impUa3;				// 内部链接

const char	str3[] = "str";		// 内部链接
static char	str4[] = "str";		// 内部链接
char		str5[] = "str";		// 外部链接

char*		str6   = "str";		// 外部链接
const char*	str7   = "str";		// 内部链接
char* const str8   = "str";		// 内部链接
const char* const str9   = "str";	// 内部链接

const char	chr	   = 'x';		// 内部链接
void funtest(int);
void funtest( int )		{}

static void funtest2(int);
void funtest2( int )	{}

typedef void (*ptr_func)(int);

template<ptr_func>
void fun6()		{}

ptr_func pfun2 = &funtest;
const ptr_func pfun3 = &funtest;
static const ptr_func pfun4 = &funtest;


int _tmain(int argc, _TCHAR* argv[])
{

	int i = 12;
	//const int idata = i;	// error 2971 局部变量不能用作非类型参数
	const int idata = 10;	// 局部常量 ok
	fun1<idata>();			// ok
	
	int idata4 = 20;
	//fun1_1<&idata2>();	// error c2970 涉及到对象内部连接的表达式不能作为 non-type argument.
	//fun1_1<&idata4>();	// error c2971 
	fun1_1<&idata3>();		// ok
	
	//fun1_2<idata2>();		// error c2970
	//fun1_2<idata4>();		// error c2971 
	fun1_2<idata3>();		// ok
	
	char		str1[]	= "string";
	const char* str2	= "string";
	//fun2<str1>();			// error c2971
	//fun2<str2>();			// error c2971
	//fun2<str3>();			// error c2970 
	//fun2<str4>();			// error c2970
	//fun2<"test">();		// error c2762 模板参数的表达式无效,为什么会无效?字符串"test"具有内部链接? 问题1。
	fun2<str5>();			// ok
	//fun2<str6>();			// error 2975 需要一个编译期常量表达式
	//fun2<str7>();			// error 2975
	//fun2<str8>();			// error c2971
	//fun2<str9>();			// error c2971

	//fun3<str2[1]>();		// error 2975 需要一个编译期常量表达式
	//fun3<str3[0]>();		// error 2975 为什么str3[0]不是编译期常量,问题2
	fun3<'x'>();			// ok
	fun3<chr>();			// ok

	// ok
	fun4_1<&impCa1>();
	fun4_2<impCa1>();

	// ok
	fun5_1<&impUa1>();
	fun5_2<impUa1>();

	//
	ptr_func pfun = &funtest;
	//fun6<pfun>();		// error c2971
	//fun6<pfun2>();	// error c2975
	//fun6<pfun3>();	// error C2970
	//fun6<&pfun4>();	// error C2970
	fun6<&funtest>();	// ok
	fun6<&funtest2>();

        return 0;
}


其他相关文章:

C++ 的内部连接(internal linkage)和外部连接(external linkage) 1--- 细节

C++ 的内部连接(internal linkage)和外部连接(external linkage) 2--- 总结

在动态库(dynamic libraries)和静态库(static libraries)使用模板(template)


  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值