C++标准库函数 end 的实现原理(非类型模板参数)

Posted yuanyb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++标准库函数 end 的实现原理(非类型模板参数)相关的知识,希望对你有一定的参考价值。

在刚开始学习《C++ Primer》的时候遇到了 end 函数,感觉很神奇,但又很迷惑:为什么能获得数组的尾后指针呢?编译器也不会在内存中申请一块空间放数组元素的个数啊!最近再一次遇到了 end 就看了一下它的实现终于明白了。

先说以下C语言中获得数组元素个数的方法。

int arr[] = 1, 2, 3;
size_t n = sizeof(arr) / sizeof(int); //n为元素个数

sizeof 返回一个常量表达式,是在编译时期确定返回值的。也就是说在编译时期是可以知道数组的长度的

 

再看看 C++标准库中 end 的实现(关键部分:非类型模板参数 N 及函数形参):

//编译器再编译时期会根据数组的元素个数来代替N,从而实例化模板
template<typename T, size_t N>
inline constexpr T* end(T (&arr)[N])  //由于不能拷贝一个数组,所以将参数定义为了数组的引用
	return arr + N; //指针和一个整数N(数组元素个数)相加,从而返回数组arr的尾后指针

模板参数列表中的 N 是一个非类型模板参数,而非类型模板参数是在编译时期被确定的常量表达式。end 函数的形参是一个(长度为N)数组的引用,因为 N 是一个非类型模板参数,所以编译器会在编译时期(前面说过,在编译时期是可以确定数组长度的)用数组的长度来初始化 N。最后将 arr 和 N 相加即获得了数组的尾后指针。

以上是关于C++标准库函数 end 的实现原理(非类型模板参数)的主要内容,如果未能解决你的问题,请参考以下文章

C++模板详解:泛型编程模板原理非类型模板参数模板特化分离编译

C++模板非类型模板参数

C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参推断

C++晋升之std中vector的实现原理(标准模板动态库中矢量的实现原理)

C++ vector类型要点总结(以及各种algorithm算法函数)

C++ Primer 5th笔记(chap 16 模板和泛型编程)重载与模板