C++11模版新特性
来源:互联网 发布:微信多开哪个软件好 编辑:程序博客网 时间:2024/06/06 01:10
模板友元
C++11新标准中,可以声明一个类的模板参数类型为类的友元。
template<typename T> class Bar{friend T;protected: int val = 100;};class Foo{public: void print_bar(Bar<Foo> &bar) {std::cout<<"bar:\t"<<bar.val<<std::endl;}};std::cout<<"test friend template type:\n";Bar<Foo> bar;Foo foo;foo.print_bar(bar);std::cout<<"test friend template type done.\n"<<std::endl;
这比以前的标准中对模版友元的支持更深入了。见博文总结:http://blog.csdn.net/u010487568/article/details/50478843。
类型模板别名
使用using语法声明新的类型别名时,也可以带上模版参数。
template<typename T> using twin = std::pair<T, T>;template<typename T> using str_int = std::pair<T, int>;std::cout<<"test template alias:\n";twin<std::string> twin_str = {"abc", "def"};std::cout<<"twin_str:\t"<<twin_str.first<<'\t'<<twin_str.second<<std::endl;str_int<std::string> strno = {"abc", 100};std::cout<<"strno:\t"<<strno.first<<'\t'<<strno.second<<std::endl;std::cout<<"test template alias done.\n"<<std::endl;
在声明str_int的时候,还可以用某一类型部分实例化模板。这是一个挺好用的特性。
模版默认参数
模版参数的默认参数,以前只支持类模版的默认参数,不支持函数摸模版的默认参数,新标准也支持了函数模版。
同时,新标准中对所有模版参数的默认值的指定,可以使用其他模版参数给出默认参数:
template<typename T, typename F=std::less<T>>int compare(const T &v1, const T &v2, F f=F()){ if(f(v1, v2)) return -1; if(f(v2, v1)) return 1; return 0;}std::cout<<"test default template parameter:\n";std::cout<<"compare int 1 2:\t"<<compare(1, 2)<<std::endl;std::cout<<"compare int 2.0 1.0:\t"<<compare(2.0, 1.0)<<std::endl;//std::cout<<"compare int 2.0 1:\t"<<compare(2.0, 1)<<std::endl; // wrong. can't determine which type is Tstd::cout<<"test default template parameter done.\n"<<std::endl;
模版参数F
使用了同时也为模版参数T
的默认参数std::less<T>
,这有些类似于模版偏特化的形式,相当于默认参数依赖与前一个模版参数。
尾置返回类型
当时用模板定义一个函数时,有时函数的返回类型是和模板参数相关的,这在以前的标准中可以使用显示实参
的方式声明多个模版参数进行:
temp1ate <c1ass T1 , c1ass T2 , c1ass T3>Tl sum(T2 , T3);//使用显示模版实参列表语法,编译器从左到右依次匹配,最后顺序匹配实参的类型long va13 = sum<long, int, long> (1, 10L);
新标准可以通过decltype获得返回类型:
std::vector<int> numbers = {1, 2, 3, 4, 5};auto iter = numbers.begin();template<typename It>auto get_begin(It beg) -> decltype(*beg){ return *beg;}auto a = get_begin(iter);//旧式解决办法使用多声明一个模版参数解决template<typename T, typename It>T get_begin(It beg){ return *beg;}int a = get_begin<*iter, iter>(iter);
上述两种方式对比很明显,可以避免多使用一个模版参数。调用起来也更方便和简介。
模版语法
extern
新增了对extern关键字的扩展,弃用了export关键字,用来进行分离模版编译模式:使得不重复生成模版实例,可以使用系统链接器,对编译器的要求更高,一般主流编译方式还是包含编译模式。
<<
和>>
智能识别
对于模版嵌套的时候出现<<
、>>
这种连续的模版边界符号,以前的编译器无法区分与输入输出流操作符的关系,导致如果是模版的时候必须使用空格隔开连续的边界符号。新标准中实现了智能区分两种情况,无需使用空格隔开。
可变参数模板
新标准中,可以定义一个不定长度的模板参数列表。
template<typename T>std::ostream &print_variadic(std::ostream &os, const T &t){ return os<<t<<std::endl;}template<typename T, typename... Args>std::ostream &print_variadic(std::ostream &os, const T &t, const Args&... rest){ os<<t<<"(remain size: "<<sizeof...(Args)<<"), "; return print_variadic(os, rest...);}std::cout<<"test variadic template:\n";print_variadic(std::cout, 100, "s", 56.76, 101);std::cout<<"test variadic template done.\n";
第一次为print_variadic
传入了4个需要打印的对象,则实例化第二个不定长模板函数,将100赋值给t
,并将剩余的3个参数打包成rest
。
在内部递归中,将不断的将rest
包中的第一个参数拿出来付给t
,剩余参数打包进行下一次递归调用。
最后只剩一个参数时,两种形式的print_variadic
都可以匹配,但是第一种没有模版参数包的版本更加特例化,因此将调用第一种形式的print_variadic
,结束递归。
新增的sizeof...()
运算符用来计算可变模版参数的个数。
还有可以定义如下的方式来构造可变参数的对象:
template<typename T>class A {public: template<typename... Args> A(Args...args){ _member = new T(args...); }//...private: T *_member;};
上述的构造函数可以依据T
类型构造时所需的不同个数的参数,使用new T(args...)
的方式进行通用的构造。
暂总结于此。
- C++11模版新特性
- C+11 新特性
- [C++]C++11新特性
- 【C++】 C++11新特性
- 【C++】了解C++11新特性
- C++:C++11新特性详解(1)
- 12c新特性
- Objective-C新特性
- Objective-C新特性
- Objective-C新特性
- Objective-C新特性
- 12C新特性
- C#7.0新特性
- Objective-c新特性
- C++函数新特性——函数模版
- 【C/C++】C++11新特性:std::bind
- Delphi2009/C++Builder2009新特性
- C 99的新特性
- linux fedora 24 安装 jekyll
- 求数列的和
- 深入浅出JMS(一)--JMS基本概念
- ubuntu14.04 sudo免密码
- centos 创建service
- C++11模版新特性
- DOM 事件流
- oracle之round函数、over()函数
- 根据关键字查找文件夹下的所有匹配文件
- typedef与#define区别
- Hadoop集群(第5期副刊)_JDK和SSH无密码配置
- Hadoop集群(第6期)_WordCount运行详解
- 用 Flask 来写个轻博客 (10) — M(V)C_Jinja 常用过滤器与 Flask 特殊变量及方法
- mysql之操作数据表中的记录