BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #74480同步于 2013/10/13
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

【来点新东西】C++11 新特性指南 —— A Morden C++

jokerlee
2013/10/13镜像同步15 回复
不知不觉C++1x也就是以前的C++0x已经基本达到工业使用的成熟度了,目前各个编译器的实现也很完整了(LLVM Clang 4.0+, VS 2010+, gcc 4.6+)。前两天把项目里的编译选项从c++98提升到了c++1x,过程很平滑,完全向下兼容,工业上很快就会大规模使用。整理了一下C++1x的新特性,有很多不错的feature,充分体现了C++的设计原则:「把语法上对程序员的限制减到最小」。 1. lambda表达式 [ref] ----------------- killer feature,简单地说就是闭包、匿名函数。没有lambda的时候,实现回调需要使用仿函数Functor(一个重载了()的类),或者用一个对象指针加一个函数指针来模拟。两种方法都无法直接在使用处定义函数,语法上非常啰嗦,而且对于参数的处理也非常不灵活。lambda大大改善了这个问题。 格式:[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()); 2. 括号初始化列表 std::initializer_list [ref] ----------------- 原来只有数组和结构体在初始化的时候才能用的{1,3,4,5}这样的字面量,现在会被转化成std::initializer_list<T>类型,这使得任意函数都可以接收这样的参数,比如标准库容器的构造函数。 vector<int> a_int_vector = {1, 2, 3, 4}; a_int_vector.add({1, 2, 3, 4}); 3. 代理构造函数 ----------------- 简单说就是构造函数可以互相调用,原来如果多个构造函数有很多相同逻辑只能挪到一个init方法里。现在可以如此实现: 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) { } } 4. 字符串字面量增强 ----------------- * unicode string * raw string literals (回想起以前在c++代码里嵌入javascript的经历,泪流满面) 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#弱爆了 5. 用户定义字面量 [ref] ----------------- 一个带来无限想像的特性 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 6. 右值引用和move语义 ----------------- 这个特性理解起来比较繁琐,主要的思想是通过充分利用右值(临时变量),来加速和避免不必要的对象构造,典型的应用是「完美转发」,下面的两篇文章讲的比较清楚。 * [详解C++右值引用] * [C++11 标准新特性: 右值引用与转移语义] 7. 强类型枚举 ----------------- 这个相对比较鸡肋 // RED GREEN BLU不会被暴露到全局namespace,并且不能被隐式转换成int enum class Color {RED, GREEN, BLUE}; namespace flags { // 如果是二进制标记位 不如实现成这样 constexpr int a = 1, b = 1<<1, c = 1<<2; } 8. 可变参数模版和参数打包 ----------------- 典型的用途之一就是后面会提到的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; } 9. constexpr [ref] ----------------- 使得函数的返回值可以具有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 在编译期被计算 10. 一些新关键字 ----------------- * auto it=a_vector.begin(); 自动类型推导 * decltype(&myfunc) a; 声明一个和x类型相同的变量a; [ref] * void func() override; 和java中的override语义类似,表示重载父类virtual方法,避免意外覆盖 * constexpr 编译期常量约定 * nullptr 类型安全的空指针,代替NULL宏,[ref] * class A final 禁止类被继承,没有类似java作用在变量声明上的imutable语义 * struct alignas(16) sse_t { float sse_data[4]; } 申明对齐方式 * long long int 类型,至少64位的整型,C99里已经标准化了 11. 标准库中的新东西 ----------------- * 多线程 [ref] * 正则式 [ref] * 智能指针:unique_ptr, 改良的shared_ptr 和 std::weak_ptr,[这篇blog]解释的比较清楚 * 哈希表 [std::unordered_set](http://en.cppreference.com/w/cpp/container/unordered_set) [std::unordered_map](http://en.cppreference.com/w/cpp/container/unordered_map) [std::unordered_multiset](http://en.cppreference.com/w/cpp/container/unordered_multiset) [std::unordered_multimap] * 非成员begin/end函数: ``` int a[100]={1,2,3}; std::sort(std::begin(a), std::end(a)) ``` * Tuple类型:alternative for struct,非常适合需要返回多个值的函数 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 * 新增算法 all_of any_of none_of copy_if iota generate 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)); // 随机填充 * 可扩展的随机数工具 [ref]:由engine、engine adapter、number generator和distibution组成 参考 ----------------- * [C++11 FAQ by Bjarne Stroustrup] * [C++11 wiki] origin from my blog http://boundary.cc/2013/10/c11-new-features/,转载请注明出处
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
gaoweiwei机器人#1 · 2013/10/14
这个不错
iFadeToBlack机器人#2 · 2013/10/14
强类型枚举还是很好的,避免出现好名字都被狗抢了的情况,而且也不用在定义枚举的时候把类型名称在枚举成员处再重复一遍,还能避免不会用枚举的人瞎用写些"magic code"
yaoniming3k机器人#3 · 2013/10/14
fentoyal机器人#4 · 2013/10/14
【 在 jokerlee 的大作中提到: 】 : 不知不觉C++1x也就是以前的C++0x已经基本达到工业使用的成熟度了,目前各个编译器的实现也很完整了(LLVM Clang 4.0+, VS 2010+, gcc 4.6+)。前两天把项目里的编译选项从c++98提升到了c++1x,过程很平滑,完全向下兼容,工业上很快就会大规模使用。整理了一下C++1x的新特性,有很多不错的feature,充分体现了C++的设计原则:「把语法上对程序员的限制减到最小」。 : : 1. lambda表达式 [ref] 比较郁闷的是刚觉着自己对C++11的掌握已经up-to-date了,又要开始学C++14了。。C++17也提上日程了。 这下委员会是效率高了,累死做编译器的吧,用户也消化不干净了,没人敢抱怨委员会了。
args机器人#5 · 2013/10/15
【 在 fentoyal 的大作中提到: 】 : : 比较郁闷的是刚觉着自己对C++11的掌握已经up-to-date了,又要开始学C++14了。。C++17(小点的revision)也提上日程了。 : 这下委员会是效率高了,累死做编译器的吧,用户也消化不干净了,没人敢抱怨委员会了。 不是说14是类似03那样的小改动,17才是新一波么。 C++现在这个委员会真是卯足了劲。
JacKie575机器人#6 · 2013/10/15
C++11之前不能内置支持多线程,还必须link pthread,还有不支持正则,真的很不科学
fentoyal机器人#7 · 2013/10/15
【 在 args 的大作中提到: 】 : : 不是说14是类似03那样的小改动,17才是新一波么。 : C++现在这个委员会真是卯足了劲。 是啊,我说反了么。。汗。。 标委会不努劲不行了,快成国足了。
TheCambrian机器人#8 · 2013/10/16
谢楼主,先留着,好想抽段时间好好学习这些新特性 可是我现在一点时间都没得[ema16]
CodingMyLife机器人#9 · 2013/10/16
link pthread是linux提供的, 【 在 JacKie575 的大作中提到: 】 : C++11之前不能内置支持多线程,还必须link pthread,还有不支持正则,真的很不科学