不知不觉C++1x,也就是之前的C++0x已经基本达到工业使用的成熟度了,各个编译器的实现也很完整了(LLVM Clang 4.0+, VS 2010+, gcc 4.5+)。前两天把项目里的编译选项从c++98提高到了c++1x,过程很平滑,彻底向下兼容。整理了一下C++1x的新特性,有不少不错的feature,充分体现了C++的设计原则:「把语法上对程序员的限制减到最小」。javascript
killer feature,简单地说就是闭包、匿名函数。没有lambda的时候,实现回调须要使用仿函数Functor(一个重载了()的类),或者用一个对象指针加一个函数指针来模拟。两种方法都没法直接在使用处定义函数,语法上很是啰嗦,并且对于参数的处理也很是不灵活。lambda大大改善了这个问题。html
格式:[capture] (parameter list) -> return type { function body } // 删除集合中小于5的值 c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < 5; } ), c.end());
原来只有数组和结构体在初始化的时候才能用的{1,3,4,5}这样的字面量,如今会被转化成std::initializer_list<T>类型,这使得任意函数均可以接收这样的参数,好比标准库容器的构造函数。java
vector<int> a_int_vector = {1, 2, 3, 4}; a_int_vector.add({1, 2, 3, 4});
简单说就是构造函数能够互相调用,原来若是多个构造函数有不少相同逻辑只能挪到一个init方法里。如今能够如此实现:c++
class Point { private: int _x, _y; public: Point() { Point(0, 0) } Point(int x) { Point(x, 0); } Point(int x, int y) _x(x), _y(y) { } }
u8"This is a Unicode Character: \u2018." u"This is a bigger Unicode Character: \u2018." U"This is a Unicode Character: \U00002018." string path = R"(C:\Program Files\A B\a.exe)"; string html = R"(<a href="http://a.com/"></a>)"; // 注意:连引号都不须要转义,C#弱爆了
一个带来无限想像的特性程序员
inline constexpr long double operator "" _deg (long double deg) { return deg*3.141592/180; } double x = 90.0_deg; // x = 1.570796 long double operator "" _s (long double s) { return s; } long double operator "" _ms (long double s) { return s * 1E3L; } long double operator "" _us (long double s) { return s * 1E6L; } std::cout << 1.0_s << std::endl; // 1 std::cout << 1.0_ms << std::endl; // 1000 std::cout << 1.0_us << std::endl; // 1000000
这个特性理解起来比较繁琐,主要的思想是经过充分利用右值(临时变量),来加速和避免没必要要的对象构造,典型的应用是「完美转发」,下面的两篇文章讲的比较清楚。算法
这个相对比较鸡肋数组
// RED GREEN BLUE不会被暴露到全局namespace,而且不能被隐式转换成int enum class Color {RED, GREEN, BLUE}; namespace flags { // 若是是二进制标记位 不如实现成这样 constexpr int a = 1, b = 1<<1, c = 1<<2; }
典型的用途之一就是后面会提到的std::tuple,或者像下面同样实现一个log方法,这篇blog中有不错的例子和讲解。安全
template<typename First, typename... Other> // ...的学名叫Parameter Pack void log(First value, Other... remaining) { std::cout << value << ","; log(remaining); } template<typename T> void log(T t) { std::cout << t << std::endl; }
使得函数的返回值能够具备const语义。申明为constexpr的函数,若是调用的时候传入的参数是常量表达式,那么其返回值会在编译期被计算,从而也是const的(c++编译器有向操做系统发展的趋势)。多线程
constexpr int exp(int a, int b) { int x = a; for (int i = 1; i < b; ++i) { x *= a; } return x; } const int a = exp(2, 10); // 1024 在编译期被计算
int a[100]={1,2,3}; std::sort(std::begin(a), std::end(a))
std::tuple<int, int, int> fun() { return std::make_tuple(1,2,3); }; int a, b, c; std::tie(a,b,c)=fun(); // 将tuple展开到三个变量中,与PHP中的list用法很是像 std::cout << a << b << c; // 123
std::list<int> l {1, 2, 3, 4, 5}; std::all_of (v.cbegin(), v.cend(), [](int i){ return i < 6; }); // true std::none_of(v.cbegin(), v.cend(), [](int i){ return i > 5; }); // true std::any_of (v.cbegin(), v.cend(), [](int i){ return i = 2; }); // true std::iota(l.begin(), l.end(), -1); // {0, 1, 2, 3, 4} std::vector<int> v(10); std::generate(v.begin(), v.end(), std::rand)); // 随机填充
原文见个人blog http://mainloop.cc/2013/10/cp...闭包