跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • C++标准库 std 里面简直就是另外一个世界
未分類
5 2 月 2021

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

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

資深大佬 : James369 7

在写 C++的时候,不小心点进 std 标准库的.h 头文件,只是看了一眼它的源代码。
我去,一堆的 template 操作,一堆的__下划线,一堆的…变参。。。
仿佛进入了另外一个世界,C++的水真深啊。
我想如果看懂 std 源码,我觉得差不多也就学成了吧。
大佬有話說 (80)

  • 資深大佬 : towry

    看懂文言文不代表能写出好的文章

  • 資深大佬 : auto8888

    能完全看懂 std 源码应该可以说得上精通 C++了吧。。。。

    ![image.png]( https://i.loli.net/2021/01/20/2NlBvkcO3qHarzT.png)

    看的想死

  • 資深大佬 : yanqiyu

    下划线只是为了避免不必要的冲突,至于一堆 template…嗯,因为人家叫做 STL

  • 主 資深大佬 : James369

    @towry 我翻译一下:精通砖头泥水铲子,但不一定会盖房子。

  • 資深大佬 : Twice

    候捷老师的 《 STL 源码剖析》 ,都是大师啊

  • 資深大佬 : Twice

    而且之前看他视频,也说其实 stl 里面一些容器类,是有优化空间的

  • 主 資深大佬 : James369

    @Twice 可以说,template 完全是另外一种编程模式,神奇

  • 資深大佬 : shunia

    我就想说 2 ,搞 C 语言就必须用这种我一眼看过去直接眼花的字体和配色吗?
    你们这些底层开发人员就不能对自己好一点,搞一些现代化的东西,非得整电话机 010101 那套吗?
    而且现在市面上方便好用的 C 的 IDE 多的是吧?

    我是真的替你们感到眼睛累。。。手动狗头

  • 資深大佬 : CismonX

    你可以把 C++ 的类型系统当作另外一门(纯函数式的)语言。如果熟悉函数式编程的思想,template metaprogramming (不限 C++)并不是非常困难

    另外提醒一下,双下划线和单下划线加大写字母开头的名称都是预留字,只有语言实现里面允许用(比如在 STL 或者 libc 中)

  • 資深大佬 : blodside

    <type_traits> 里面的那堆东西更有意思,模板真好玩

  • 資深大佬 : myid

    炫技往往是坑,容易走火入魔。

    不在其位,别谋其政。如果不是开发基础库,那么用不着那些个。C++ 和 C 的妙处根部不在于用了多少它的特性,而在于如何用尽可能它的最简单的特性最高效的完成既定任务。

    话一句话说,能用 struct 搞定的,别硬用 class 。能用普通函数搞定的,没必要非得 template 化。能用 C 风格的字符数组搞定,就没必要用 std::string 类。

    简单是力量的保证。直白易懂是可持久可维护的护身符。

  • 資深大佬 : defphilip

    里面的 template 完全就不难啊。。。就一堆类型推导

  • 資深大佬 : hitmanx

    不同的编程范式带来的陌生感。

  • 資深大佬 : XIVN1987

    @myid
    你这说法和书上说的不一样啊

    书上都说能用 std::string,不用 C 风格的字符数组;能用 std::array,不用 C 风格的数组

  • 資深大佬 : focux

    那你还不如看 boost 源码呢

  • 資深大佬 : skyworker

    泛型是当时 C++的一个风格, 忘记了好像是相对于”对象 /继承”这种 “运行时多态” 之外, 通过 template 技术来实现 “编译时多态”, 不过貌似当时被排斥为”异端”

  • 資深大佬 : auto8888

    @shunia IDE 是 qt creator 主题 dark 字体 courier 请指教 /doge

  • 資深大佬 : abc612008

    @myid 建议直接用 c

  • 資深大佬 : 1490213

    组里部分老 C++ 代码不好的两个倾向:
    一,追求技巧和花样,县城盖白宫。
    二,半吊子整出的幺蛾子多,配合起来困难。

  • 資深大佬 : shunia

    @auto8888 #17 我不是 C 程序员,完全不懂哈,我只是觉得您的截图,字体和配色太花眼了,我第一眼看过去就觉得看代码的成本太高。虽然 IDE 只是点缀,但是从某一个角度来说,配合熟练并且本身就更优秀的 IDE,应该相对来说更能提高工作效率。当然这点我有点主观,看看就好。

    另外如果只考虑 IDE 本身,并且非要推荐的话:
    假如没有特殊情况的话,比如 sublime text,相对来讲默认样式要养眼很多。
    再现代化的就可以考虑 vscode 或者 Jetbrain 家的产品是否能满足你的开发要求。

    我不懂 C/C++,所以考虑不到这些 IDE 是否适合对应的工作流。

  • 資深大佬 : shunia

    ![比如我用 sublime 打开 libwebp 的情况,相对来说要清晰很多吧?]( https://tva1.sinaimg.cn/large/008eGmZEly1gmu0v44k6rj31d90u0b0c.jpg)

  • 資深大佬 : mingl0280

    @myid
    我想避免满天飞的 void*,所以才用 template 的……
    因为以前的代码是 C 升级上来的,真的是满天飞的 unnamed type 和 void*以及各种强制类型转换,这种时候你就知道 C++的带类型和语义化的好处了。
    另外,C 风格字符数组这个东西我现在跟我同事说了,不是万不得已不要用,因为有些东西根本不应该被转换为字符数组,而有些东西你用字符数组带来的裸指针的麻烦比用容器更大。

  • 資深大佬 : aihimmel

    可读性高的 stl
    https://github.com/electronicarts/EASTL

  • 資深大佬 : Jirajine

    当你对 c++感到蛋疼的时候,去看看 rust,你会发现一个新世界。

  • 資深大佬 : Leviathann

    @Jirajine 是更蛋疼还是相反。。

  • 資深大佬 : e583409

    @Jirajine 洗耳恭听

  • 資深大佬 : XIVN1987

    @Jirajine
    语法和 C 、C++、C#、JAVA 这些 C-like 都不一样,,至少从语法上肯定是个新世界

  • 資深大佬 : AlohaV2

    template 比 macro 绝大多情况下友好多了,相信我。
    STL 的作用就是让使用者不必关心这些实现细节,除非使用者要讲究细节。
    自己的库封装给用户的时候,不一定 template 就为王,要根据场景而定的。最好的结局是尽管你可能用到了 template,但是用户使用的时候几乎无感。

  • 資深大佬 : nightwitch

    @myid
    在 C++里面 class 和 struct 除了默认的访问和继承权限不一样以及 template class 以外,其他是一个东西

  • 資深大佬 : nnqijiu

    c 风格和 c++风格混用才是 c++让人蛋疼的地方

  • 資深大佬 : nightwitch

    https://github.com/electronicarts/EASTL
    推荐 EASTL,名字没有混淆过(因为命名空间在 eastl::),虽然不是完整的标准库,但是可读性很好,读起来和普通 c++代码差不多。

    其实标准库没有想象的难,因为标准库的实现的东西都有 cppreference 可以参考,各个模块之间耦合也不深,而且可以多个标准库(libc++,libstdc++,msvcSTL)和仿标准库(eastl, folly)交叉验证着读,除了 iostream 之类的糟粕以外,容器和算法读起来都应该不会有太多困难。

  • 資深大佬 : wdhwg001

    标准库都难读的话 ranges 岂不是更魔法文字…

  • 資深大佬 : AndyAO

    template 是元编程技术,对于很基础的类库,使用元编程技术能够极大地提升开发效率,但是由于直接对语言本身进行了改动,所以相比起其他的代码,你需要更多的学习才能看懂.

    其他语言的类库也会大量的利用元编程技术,例如 Java 的 Spring(反射)和 Ruby on Rails.

    当然,如果单纯看元编程的灵活性,在这方面最厉害的是 LISP 以及方言.

    以上观点参考自松本行弘的<代码的未来>

  • 資深大佬 : neocanable

    哎,我觉得我从来就没有学会过 c++

  • 資深大佬 : yazinnnn

    rust 不是 c-like ?

  • 資深大佬 : myid

    @abc612008 C++有它的好处。我们不妨取二者最好的部分来用。

  • 資深大佬 : myid

    @nnqijiu 好奇中。举一个小例子?
    @neocanable 你不是一个人在战斗。。。

  • 資深大佬 : myid

    @XIVN1987 绝大多数 C++书这么讲。我信了,直到动手编写代码到了一定量,遇到坑,才醒悟。别盲目相信书。卖瓜的都说瓜甜,卖风油精的讲治百病。C++标准库里的 std::string, std::set 等不见得符合“简单、直接、齐活”的要求。以前对 c-style char array 很不待见,如今领会到了它存在的理由和价值。好比武器,不一定越高级,功能越齐全,就越好越适合。

  • 資深大佬 : l00t

    @myid #36 C++ 和 C 揉在一起就是它最坑的部分。

  • 資深大佬 : myid

    @towry 妙语!赞。

  • 資深大佬 : myid

    @l00t 把 C++和 C 最混沌最难用最易出错最危险的揉在一起,是最坑的。

  • 資深大佬 : salamanderMH

    侯捷的《 STL 源码剖析》,看了才知道水很深。

  • 資深大佬 : 786375312123

    @myid “能用 C 风格的字符数组搞定,就没必要用 std::string 类。”

    啊?

  • 資深大佬 : stirlingx

    学一下 erlang,你会发现变量不能赋值

  • 資深大佬 : Narcissu5

    让我想起了一段 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

    std 是 stl 的命名空间

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

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

    所以说这套库的意义和场景都远远不能覆盖实际开发,千万不要为了模仿 stl 把自己的代码搞得不伦不类

  • 資深大佬 : SmartKeyerror

    看到有人说在 C++里面使用 C 字符串和数组我就放心了[手动狗头]。

  • 資深大佬 : levelworm

    我觉得 vector 和 string 还是要比 C 风格的要好些了吧?

  • 資深大佬 : laminux29

    std 里的东西,有些很好,比如各种算法库;但有些又不一定好,比如 vector,脱裤子放屁做了很多不需要的功能。

    根据自己的需求,合理选择这些东西,才是正解。

  • 資深大佬 : codyfeng

    @laminux29 #49 怎么会,std::vector 是 STL 少数几个用起来不用想太多的 container 了,其他 set 、unordered_set 、map 、unordered_map 每次用之前我都得想一下他的特性、实现和性能。记得 Bjarne Stroustrup 曾经提过,如果不知道要用什么 container,就用 std::vector 。

  • 資深大佬 : travo

    这恰恰说明了 C++这门语言很糟糕。
    工具是为了干活,但一种工具如果极其晦涩难用,就该换工具了。
    ————————————————–
    在写 C++的时候,不小心点进 std 标准库的.h 头文件,只是看了一眼它的源代码。
    我去,一堆的 template 操作,一堆的__下划线,一堆的…变参。。。
    仿佛进入了另外一个世界,C++的水真深啊。
    我想如果看懂 std 源码,我觉得差不多也就学成了吧。

  • 資深大佬 : mxalbert1996

    @myid 我觉得可能只有你一个人觉得 C 风格字符串比 std::string 更易懂。

  • 資深大佬 : agagega

    标准库里面的实现当然是在填坑所以代码复杂..而且标准本身可能有些细节作为普通用户也没注意到(比如 iostream 的 api 本身就很复杂)另外还有 std::function 这种本身就需要一点 C++的魔法才能学会的东西。

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

    C++随着几个标准更新和编译器变得越来越牛逼,现在已经逐渐变得不坑了。所以不要吐槽新标准,没人想回到连模版两个尖括号都没法连着写的时代吧?

  • 資深大佬 : no1xsyzy

    @myid ……你这是 C with objects
    这种做法本身倒并不是什么问题,似乎从 C++ 出来就一直很热门的做法,不过这么用的人几乎都不会说自己在用 C++,都是在说自己在用 C with objects
    “直白易懂”你在指 Golang ?

    @James369 你可能不知道,template 语法是图灵完备的。
    见过别人写的编译期筛法素数表,搞出一堆 IsPrime<3, true> IsPrime<4, false> 这种类型
    那才叫真炫技(确实毫无卵用)

  • 資深大佬 : inframe

    把 C++当 java 写,比较容易统一风格

  • 資深大佬 : ipwx

    上一堆没写过算法吧? C++ 的模板类是所有语言里面唯一有那么强大的抽象能力,还能保持零开销的奇葩存在了。

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

    再比如多维张量中,所有维度都已知长度的小张量可以在堆上分配内存,而有些维度未知长度的大张量可以使用堆内存。这样能得到更高的效率。

  • 資深大佬 : liuminghao233

    之前看了 asio 的代码头都裂开了

  • 資深大佬 : jsyangwenjie

    @myid 这几句话没一句对的。。

  • 資深大佬 : neoblackcap

    @yazinnnn 受 ML 系的影响更大,里面一堆函数的用法。对类型系统的推崇

  • 資深大佬 : owenliang

    个人感觉:精通现代 C++的 template 语法,难度不亚于精通主流机器学习算法的推导与实现。

  • 資深大佬 : laminux29

    @codyfeng vector 在有些情况下,会自作主张调用析构函数。

  • 資深大佬 : 12101111

    @ipwx rust? macro_rules! #[proc_macro]

  • 資深大佬 : 429839446

    @nightwitch 在 ms 的系统里会影响 abi, 混用 clang 会出警告..

  • 資深大佬 : codyfeng

    @laminux29 原来如此,vector resize 需要重新分配空间的时候的确会发生这种情况。可以如此解决
    1 、实现 move constructor
    2 、往 vector 塞东西前 reserve

    这个不能怪 vector,即使自己管理内存,需要重新分配空间时也有同样的问题。

  • 資深大佬 : hobochen

    @ipwx 话得反过来说才对,C++是零开销语言里面抽象能力最强的;更强大的抽象能力还是得看看 functional 的那一大堆

  • 資深大佬 : siyemiaokube

    @hobochen
    个人感觉 cpp 现在已经非常 functional 了……

  • 資深大佬 : nmap

    做基础库( stl/boost 等)的人,跟做应用开发的人,不是一个 level 的。。。

  • 資深大佬 : fixend

    vs 的 stl 的代码风格看起来是很难理解,
    总感觉那代码是做过代码混淆的,为了防止别人抄袭,
    我没记错的话,这库是微软买的。

    应该看 clang 的 stl 库,清晰不少。

    然后,boost 库才是真会看得怀疑人生,各种模板技巧,大量 N 层嵌套的宏。

  • 資深大佬 : togou

    委员会那帮人 C++ 差不行么? 不说精通 比大部分专家 怕是要好吧

  • 資深大佬 : hobochen

    @siyemiaokube 没反射(甚至连编译器反射都没有)怎么和那些 type as data 的语言比啊

  • 資深大佬 : hobochen

    @hobochen 编译期

  • 資深大佬 : ipwx

    @hobochen 你说得对
    @12101111 rust 也行嘛,是我孤陋寡闻了。

  • 資深大佬 : stevefan1999

    @ipwx Rust

  • 資深大佬 : dyv9

    @shunia 你觉得作者和你用的是一样的 开发工具?太天真了吧。指不定人家的工具自动化水平非常高,写两段伪码剩下的自动翻译成源代码呢。

  • 資深大佬 : dyv9

    虽然 我不懂 C++,但我觉得 既然是标准库,一定是一群人讨论后觉得这个方案是适合大部分人,能解决大部分问题的普适方案,如果你的问题很特殊,那我相信你应该已经是专家,知道怎么解决问题,并不必须依赖标准库。

  • 資深大佬 : lakehylia

    提供出去的接口千万不要用 stl,都是泪。。。

  • 資深大佬 : myid

    @mxalbert1996 不是 C 风格字符串更易懂,而是当 C 风格字符串就够用了,那么就用不着 std::string 了。当 C 数组就可以了,用不着非得用 std::vector 。

    std::string 作为处理字符串的类,横向对比 Python, Java 等类似的实现,就显得很残很废很单薄。是不是?

  • 資深大佬 : myid

    @SmartKeyerror C++里不使用 C 字符串和 C 风格数组,是一种迷信。

  • 資深大佬 : mxalbert1996

    @myid 「简单是力量的保证。直白易懂是可持久可维护的护身符。」这是你自己说的,我只能理解为你觉得 C 风格字符串比 std::string 更简单易懂。

  • 資深大佬 : ipwx

    @owenliang 噗哈哈哈哈。这个比喻

    我个人的话:template 不说精通,让我写个 stl 没压力。
    机器学习不算大牛,让我推导主流网络结构公式都没压力。我的研究方向是 deep Bayesian network

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具