以后全部的C++文章就在这里落脚了, C++17也在这里更新.
这里集中说一说, 就当汇总吧; 以后C++更新的新内容全部在此
. 更新列表, 如下:
时间 | 内容 |
---|---|
2017-8-26 | 初稿:C++标准文档 |
2017-9-14 | 更新:C++17新特性(参考《程序员杂志》,2017.09期) |
2017-10-03 | 技术就是条无底洞, 尤其C++, 我不了解的内容还有很多; 遂修改部分言论 |
在今天这语言百花齐放的年代, C++标准的制定又
被资金限制
推迟, 一直是在追着时代跑(已经完全不能领先于时代了)
C++的著作, 非常多, 鱼龙混杂. 我当年走了不少弯路; 实际上很多书可以不读.
经典著作
我在最开始写 Modern C++
的时候, 就推荐过好基本书, 这里在集中说一说.
入门我一共推荐了2本: (入门你看看《C++编程语言-十周年版》也是不错的, C++本加尼写的)
- 《C++语言演化》
- 《C++ Primer(5e)》 (不要看第四版)
我一共推荐4本C++的额外读物:
- 《Effective Modern C++》
- 《Effective C++ 第三版》(相比第二版有很多新东西)
- 《More Effective C++》
- 《Effective STL》
后面3本是经典, 需要细读.
由于我不是专门研究或者参与语法研究, 我其实不太喜欢语法来语法去, 也比较讨厌硬是把给个主题都写一遍的书, 比如《Think In C++》
.
(纯粹的浪费大好的青春, 年华)
还有一些, 比如《Inside C++ Object Mode》
, 我只能说, 如果你还在上学, 请务必读一读; 如果已经工作, 呵呵, 你好闲啊.
标准文档
C++真正正式公布的标准只有三个:C++98、C++03、C++11:
- C++98是第一个正式的C++标准
- C++03是在C++98上面进行了小幅度的修订
- C++11则是一次全面的
大进化
(之前称C++11为C++0x,以为会在08~09年公布,没想到拖到了11年, 原因?缺钱
啊)
(你看它的标准文档就知道了, 前两个版本都是2.7M左右, C++11直接变成了14M)现在貌似C++17标准也快了, 据说9月就会去开会讨论啥的. 不过C++标准的跳票也没准, 就像官方所说的, 缺乏资金推动.
下面给出标准库的文档, 可以参考我的github库:
C++98 (1998年)
https://github.com/WizardMerlin/Gate/tree/master/appendix/98.pdf
C++03 (2003年)
https://github.com/WizardMerlin/Gate/tree/master/appendix/03.pdf
C++11 (2011年)
https://github.com/WizardMerlin/Gate/tree/master/appendix/11.pdf
如果有时间, 这些文档是值得好好读读的, 而且是
一手资料
C++17
C++17是语言小修改(相对C++14,大概20几条)、标准库增加比较多(大概200多条)。
C++20将会是可以和C++11可以媲美的大发展。
程序员杂志上《深入应用C++11》的作者给出了介绍, C++17其实主要是把Boost已经运用成熟的特性, 比如any
, optional
, filesystem
等引入.
还有一些简化代码的机制, 比如nested namespace
, if init
, dedution guide
等; 当然还增加了并行算法
.
下面挑选我认为比较有意义的, 记录一下.
来自Boost
类型擦除的三个:
- std::any
- std::optional
- std::variant
其中, std::optional
一般用于返回值(返回不确定值), 而std::any
, std::variant
则用于存储任意类型的值, 只是在转换回来时, std::any,
需要使用std::any_cast<类型>
, 而 std::variant 则用 std::get即可, 当然你用std::visit(functor, arg)
也可以.
std::filesystem
基本和boost中的一致, 用来处理文件和目录, 比如:1
2
3
4
5
6namespace fs = std::filesystem;
std::string path = "C:\\test";
for(auto& p : fs::directory_iterator("test"))
{
std::cout << p << std::endl;
}
简化代码
这里最显著的就是, 嵌套的命名空间, 例如C++11会这么写:1
2
3
4
5
6
7
8
9
10
11namespace A
{
namespace B
{
namespace C
{
struct Foo{};
//...
};
};
};
然后C++17就直接这么搞:1
2
3
4
5namespace A::B::C
{
struct Foo{};
//...
};
static_assert
原来的静态断言, 你必须制定错误提示, 现在不用了, 直接给单个参数就好了, 下面是对比1
2static_assert(false, "sth. wrong"); //C++11
static_assert(false); //C++17, let compiler do message
条件初始化
在if语句里面初始化相关判断的变量, 之后if代码块执行完毕, 自动析构; 多好. 直接看例子吧: (举锁的例子)
C++11我们这么写的一段代码:1
2
3
4
5
6
7
8
9std::mutex mtx;
std::vector<int> v;
{
std::lock_guard<std::mutex> lock(mtx);
if(v.empty()) {
v.emplace_back(1);
}
}
凸出来的一段{ }
代码块, 好看么? 再看看C++17, 直接起飞:1
2
3
4
5
6
7std::mutext mtx;
std::vector<int> v;
if(std::lock_guard<std::mutex> lock(mtx); v.empty())
{
v.emplace_back(1);
}
演绎推导deduction guide
有人还是很羡慕 JAVA的菱形语法
, 但是C++17可以直接省略泛型, 编译时会自动推导:1
std::pair p(1,1.5);
直接推导为1
std::pair<int, double> p(1, 1.5);
也就是说, 进行了隐式推导.
当然你可以去写
显示推导
表达式, 个人认为比较麻烦, 除非你在写框架, 需要定义大量模板
capture *this
lambda表达里面捕获外部的值, 以值传递
的方式, 还是有的, 比如说, 在main线程里面, 你给A线程传递一个值, 这个时候传引用么? 可以么? 就怕真到A线程执行的时候, main线程已经改变这个值了, 要想保证A线程拿到的, 就是你main线程, 开启A线程时传递的值, 怎么办? 值传递
啊.1
2[=, copy=*this]{} //C++11
[=, *this]{} //C++17
还有一些其他的特性, 感觉
小修补
, 还不错.
算法部分
std::search算法, 有点类似std::find_first_of
, 但是它比find_first_of 更加适用于查找子串, 因为这个算法是以子串整体为单位.
再有就是并行算法
.
说并行算法, 我们说的最多的就是, 你开俩线程, 累加一个数组的前半部分和后半部分
现在有了并行算法, 比如你拿std::reduce
这个并行算法, 代替原来的 std::accumulate
求和, 性能直接翻翻, 还多.
但是并行算法, 因为是标准指出的, 就看编译器怎么实现, 怎么去支持了…
其他
其他部分, 再说吧, 小修小补, 还行吧, 以后在说?