在上一篇文章中,我们讲到了nullptr、auto、decltype、for,得益于这些新特性,我们写出的程序更加安全、简洁。如果你还不了解,请移步至超好用的C++11新特性(一)。今天,我们将继续讲解C++11新特性。
1.编译期常量
在C++里用关键字const可以定义常量,例如:
const int k=1024; // 整数常量,值为1024
但这样的“常量”实际上是运行时不可修改的“常量”,在泛型编程里有时会需要在编译期可用的“真正的”常量。于是C++11/14增加了新关键字constexpr,它相当于编译期的const,但功能更强,可以让编译器更好地优化代码,例如:
constexpr int kk=1024;
2.类型别名
在原本的C++98标准中,你能用到关键字using的地方估计只有using namespace std;
了。但是在C++11/14里扩展了using关键字的能力,可以完成与typedef相同的工作(为类型取一个别名)。例如:
using int64=long; // long类型的别名是int64
using llong=long long; // long long类型的别名是llong
这种类似于赋值的语句,使我们更加容易阅读和理解。但实际上using的能力远不止于此,它还可以结合template关键字为模板类声明“部分特化”的别名。例如:
template<typename T>
using int_map = std::map<int,T>; // 固定key类型为int
int_map<std::string> m; // 使用别名,省略了一个模板参数
3.可变参数模板
C/C++的函数支持可变参数,允许函数接收任意数量的参数,最典型的就是printf():
int printf(const char *format, ...);
为了更好地支持编译器的模板元编程,C++11/14标准引入了与之类似的特性。语法十分相近,同样使用了省略号“...”来声明不确定数量的参数。例如:
template<typename ... T> void some_func(){};
在传入不确定个数的参数之后,我们需要对参数包进行展开,展开的方式多种多样:递归、逗号表达式、模板偏特化、继承。由于篇幅限制,在这里我就只举一个递归的例子:
template<typename T,typename... Args>
void print(T head,Args... args) // 展开函数
{
std::cout<<head<<std::endl; // 打印一个参数
print(args); // 递归打印
}
template<class T>
void print(T t) // 递归终止函数
{
std::cout<<t<<std::endl;
}
这样,上面的两个print()函数基本就被封装成了万能打印函数。
结语
下面还会继续讲解C++11的新特性,喜欢的朋友请点个赞吧!
网友评论