常量表达式
C++11规定使用constexpr修饰符来修饰常量表达式。常量表达式可以是函数或者值。常量表达式函数中不可以出现非常量表达式。常量表达式可以在编译期使用,但如果常量表达式并没有一定要在编译期被计算出来,标准规定编译器在这种情况下可以将常量表达式编译成普通的表达式,表达式会在运行时被计算。
变长模板
过去,C++可以使用C风格的方法来实现可变参函数,但这种实现方式是类型不安全的。
现在,C++11为可变参函数提出了更合理(类型安全)的解决方案:变长模板。可以使用变长模板来声明变长模板函数或者变长模板类。
模板参数包与递归
使用template <typename... Elements>这种方式可以声明一个变长模板参数,使用Elements...这种方式可以将变长模板参数展开成实际的多个参数类型;
不定长的变长模板类可以通过模板类的递归来解包:
template <typename... Elements> class tuple; // 变长模板声明
// 以下是两个模板偏特化定义,利用模板偏特化会被优先匹配的规则,让变长模板参数递归地被解包
// 对于类型,可以使用递归的继承
template <typename Head, typename... Tail>
class tuple <Head, Tail...> : private tuple<Tail...> {
Head head;
}
template <> class tuple {};
// 对于函数,可以使用递归的函数调用
// 下面实现一个更强大的Printf,不论%后面跟的是什么符号,这个Printf总是会打印正确的类型
void Printf(const char* s) {
while (*s) {
if (*s == '%' && ++s != '%') {
throw runtime_error("invalide format");
}
cout *s++;
}
}
template <typename T, typename... Args>
void Printf(char* s, T value, Args... args) {
while(*s) {
if (*s == '%' && *s++ != '%') {
cout << value;
return Printf(++s, args...);
}
cout << *s++;
}
// 若百分号的数量和参数数量对不上,就抛异常
throw runtime_error("extra arguments provided");
}
进阶
引用类型
定义了模板参数包后,还可以在展开模板参数包时使用引用标记:Args&&...,这样的写法是合法的;
特殊展开
解包时,有些非常特殊的规则,需要特别说明一下:
template <typename... Args> class MyCls: private A<Args>... {};
// 上面的表达式在解包时会解包成多继承:
T<Parent1, Parent2> t; // t的类型是:class MyCls: private A<Parent1>, A<Parent2>
template <typename Args...> class MyCls: private A<Args...> {};
// 而这个表达式在解包时,会在泛型参数表达式中直接展开
T<Parent1, Parent2> t; // t的类型是:class MyCls: private A<Parent1, Parent2>
template <typename Args...> void test(Args... args) {
// 下面这个会被展开成call(a(arg1), a(arg2), ...)
call(a(args)...);
// 而下面这个会被展开成call(a(arg1, arg2, ...))
call(a(args...));
}
获取变长参数包长度
可以使用sizeof...获取模板参数包的长度;
模板的模板(的模板的模板...)
变长参数的模板类型本身也可以是一个模板,这一点和以前的非变长模板参数一样。
原子类型和原子操作
C++11以前,已经有很多使用多线程能力的C++程序了,但之前语言本身并没有定义任何同多线程有关的内容,这些多线程能力来自于多线程接口pthread。pthread是一套C的接口。
通常情况下,如果我们不需要太精细的互斥控制,可以直接使用posix提供的mutex互斥锁API,而如果想达到更优化的性能,可能会考虑为不同处理器编写内敛汇编代码。
C++11标准为多线程程序在标准库中添加了原子类型,并允许指定原子类型的内存访问顺序一致性,让开发者可以不必操心操作系统和处理器的底层细节,也可以获得最优化的性能。