C++标准库 std 里面简直就是另外一个世界

2021-01-20 09:51:40 +08:00
 James369
在写 C++的时候,不小心点进 std 标准库的.h 头文件,只是看了一眼它的源代码。
我去,一堆的 template 操作,一堆的__下划线,一堆的...变参。。。
仿佛进入了另外一个世界,C++的水真深啊。
我想如果看懂 std 源码,我觉得差不多也就学成了吧。
11762 次点击
所在节点    C++
83 条回复
myid
2021-01-20 16:25:52 +08:00
@l00t 把 C++和 C 最混沌最难用最易出错最危险的揉在一起,是最坑的。
salamanderMH
2021-01-20 16:38:21 +08:00
侯捷的《 STL 源码剖析》,看了才知道水很深。
786375312123
2021-01-20 17:17:55 +08:00
@myid “能用 C 风格的字符数组搞定,就没必要用 std::string 类。”

啊?
stirlingx
2021-01-20 19:23:29 +08:00
学一下 erlang,你会发现变量不能赋值
Narcissu5
2021-01-20 19:31:08 +08:00
让我想起了一段 play2 里面的 scala 代码:

class ApplicativeOps[M[_],A](ma:M[A])(implicit a:Applicative[M]){

def ~>[B](mb: M[B]):M[B] = a(a(a.pure((_:A) => (b:B) => b), ma),mb)
def andKeep[B](mb: M[B]):M[B] = ~>(mb)

def <~[B](mb: M[B]):M[A] = a(a(a.pure((a:A) => (_:B) => a), ma),mb)
def keepAnd[B](mb: M[B]):M[A] = <~(mb)

def <~>[B,C](mb: M[B])(implicit witness: <:<[A,B => C]): M[C] = apply(mb)
def apply[B,C](mb: M[B])(implicit witness: <:<[A,B => C]): M[C] = a(a.map(ma,witness),mb)
GeruzoniAnsasu
2021-01-20 20:47:07 +08:00
std 是 stl 的命名空间

而 stl 是 standard TEMPLATE library 的缩写,标准库本来就是为了写成模板才写成这个样子的。

大多数语言的标准库:为了方便我们的使用者快速造车,我们先把 IO / 文件系统 / 网络库的轮子造好
c++的标准库: 卧槽我发现我们发明的模板好像能搞些骚操作,让我尝试实现一套无类型的数据结构



所以说这套库的意义和场景都远远不能覆盖实际开发,千万不要为了模仿 stl 把自己的代码搞得不伦不类
SmartKeyerror
2021-01-20 21:35:56 +08:00
看到有人说在 C++里面使用 C 字符串和数组我就放心了[手动狗头]。
levelworm
2021-01-20 21:44:48 +08:00
我觉得 vector 和 string 还是要比 C 风格的要好些了吧?
laminux29
2021-01-20 21:45:37 +08:00
std 里的东西,有些很好,比如各种算法库;但有些又不一定好,比如 vector,脱裤子放屁做了很多不需要的功能。

根据自己的需求,合理选择这些东西,才是正解。
codyfeng
2021-01-20 21:51:02 +08:00
@laminux29 #49 怎么会,std::vector 是 STL 少数几个用起来不用想太多的 container 了,其他 set 、unordered_set 、map 、unordered_map 每次用之前我都得想一下他的特性、实现和性能。记得 Bjarne Stroustrup 曾经提过,如果不知道要用什么 container,就用 std::vector 。
travo
2021-01-20 22:03:08 +08:00
这恰恰说明了 C++这门语言很糟糕。
工具是为了干活,但一种工具如果极其晦涩难用,就该换工具了。
--------------------------------------------------
在写 C++的时候,不小心点进 std 标准库的.h 头文件,只是看了一眼它的源代码。
我去,一堆的 template 操作,一堆的__下划线,一堆的...变参。。。
仿佛进入了另外一个世界,C++的水真深啊。
我想如果看懂 std 源码,我觉得差不多也就学成了吧。
mxalbert1996
2021-01-20 22:17:14 +08:00
@myid 我觉得可能只有你一个人觉得 C 风格字符串比 std::string 更易懂。
agagega
2021-01-20 22:38:16 +08:00
标准库里面的实现当然是在填坑所以代码复杂..而且标准本身可能有些细节作为普通用户也没注意到(比如 iostream 的 api 本身就很复杂)另外还有 std::function 这种本身就需要一点 C++的魔法才能学会的东西。

其实你去看其他大一点的开源项目,核心逻辑可能你都懂,但代码看着还是难受,因为大量都是在处理你可能根本没想到的特殊情况。

C++随着几个标准更新和编译器变得越来越牛逼,现在已经逐渐变得不坑了。所以不要吐槽新标准,没人想回到连模版两个尖括号都没法连着写的时代吧?
no1xsyzy
2021-01-20 22:48:10 +08:00
@myid ……你这是 C with objects
这种做法本身倒并不是什么问题,似乎从 C++ 出来就一直很热门的做法,不过这么用的人几乎都不会说自己在用 C++,都是在说自己在用 C with objects
“直白易懂”你在指 Golang ?

@James369 你可能不知道,template 语法是图灵完备的。
见过别人写的编译期筛法素数表,搞出一堆 IsPrime<3, true> IsPrime<4, false> 这种类型
那才叫真炫技(确实毫无卵用)
inframe
2021-01-20 23:13:15 +08:00
把 C++当 java 写,比较容易统一风格
ipwx
2021-01-20 23:59:38 +08:00
楼上一堆没写过算法吧? C++ 的模板类是所有语言里面唯一有那么强大的抽象能力,还能保持零开销的奇葩存在了。

如果一个 virtual function 调用的开销都无法接受,只能接受 template class 的 function 进行 inline 内联场景下,你们就知道 C++ 模板的价值了。对,我说的就是 C 语言的函数指针都比不上的部分。模板特例化可以把优化运用到极致。比如快排 C 语言版 qsort 得传进去一个函数指针,有一次函数调用。而 C++ 的 std::sort 完全可以内联掉比较器

再比如多维张量中,所有维度都已知长度的小张量可以在堆上分配内存,而有些维度未知长度的大张量可以使用堆内存。这样能得到更高的效率。
liuminghao233
2021-01-21 01:24:41 +08:00
之前看了 asio 的代码头都裂开了
jsyangwenjie
2021-01-21 03:39:46 +08:00
@myid 这几句话没一句对的。。
neoblackcap
2021-01-21 03:45:50 +08:00
@yazinnnn 受 ML 系的影响更大,里面一堆函数的用法。对类型系统的推崇
owenliang
2021-01-21 09:48:22 +08:00
个人感觉:精通现代 C++的 template 语法,难度不亚于精通主流机器学习算法的推导与实现。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/746540

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX