C++标准库 std 里面简直就是另外一个世界 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
James369
V2EX    C++

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

  •  
  •   James369 2021-01-20 09:51:40 +08:00 12658 次点击
    这是一个创建于 1776 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在写 C++的时候,不小心点进 std 标准库的.h 头文件,只是看了一眼它的源代码。
    我去,一堆的 template 操作,一堆的__下划线,一堆的...变参。。。
    仿佛进入了另外一个世界,C++的水真深啊。
    我想如果看懂 std 源码,我觉得差不多也就学成了吧。
    第 1 条附言    2021-01-20 11:23:25 +08:00
    我认为并不是炫技,std 库从侧面表明,编写 sdk 或封装库给别人使用时,也应该采用 template 这种模式?。
    第 2 条附言    2021-01-21 09:17:19 +08:00
    有些 v 友提到 C/C++混用会产生较多问题,那么是否可以用 g++指定编译 C++来避免
    83 条回复    2021-08-09 20:53:54 +08:00
    towry
        1
    towry  
       2021-01-20 09:58:11 +08:00   2
    看懂文言文不代表能写出好的文章
    auto8888
        2
    auto8888  
       2021-01-20 10:06:04 +08:00
    能完全看懂 std 源码应该可以说得上精通 C++了吧。。。。

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

    看的想死
    yanqiyu
        3
    yanqiyu  
       2021-01-20 10:06:25 +08:00 via Android
    下划线只是为了避免不必要的冲突,至于一堆 template...嗯,因为人家叫做 STL
    James369
        4
    James369  
    OP
       2021-01-20 10:08:42 +08:00
    @towry 我翻译一下:精通砖头泥水铲子,但不一定会盖房子。
    Twice
        5
    Twice  
       2021-01-20 10:10:22 +08:00   1
    候捷老师的 《 STL 源码剖析》 ,都是大师啊
    Twice"
        6
    Twice  
       2021-01-20 10:11:50 +08:00
    而且之前看他视频,也说其实 stl 里面一些容器类,是有优化空间的,但是还远没这水平
    James369
        7
    James369  
    OP
       2021-01-20 10:13:10 +08:00
    @Twice 可以说,template 完全是另外一种编程模式,神奇
    shunia
        8
    shunia  
       2021-01-20 10:44:55 +08:00   1
    我就想说 2 楼,搞 C 语言就必须用这种我一眼看过去直接眼花的字体和配色吗?
    你们这些底层开发人员就不能对自己好一点,搞一些现代化的东西,非得整电话机 010101 那套吗?
    而且现在市面上方便好用的 C 的 IDE 多的是吧?

    我是真的替你们感到眼睛累。。。手动狗头
    CismonX
        9
    CismonX  
       2021-01-20 10:47:21 +08:00 via iPhone   2
    你可以把 C++ 的类型系统当作另外一门(纯函数式的)语言。如果熟悉函数式编程的思想,template metaprogramming (不限 C++)并不是非常困难

    另外提醒一下,双下划线和单下划线加大写字母开头的名称都是预留字,只有语言实现里面允许用(比如在 STL 或者 libc 中)
    blodside
        10
    blodside  
       2021-01-20 10:50:07 +08:00
    <type_traits> 里面的那堆东西更有意思,模板真好玩
    myid
        11
    myid  
       2021-01-20 10:53:50 +08:00   8
    炫技往往是坑,容易走火入魔。

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

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

    简单是力量的保证。直白易懂是可持久可维护的护身符。
    defphilip
        12
    defphilip  
       2021-01-20 10:59:43 +08:00
    里面的 template 完全就不难啊。。。就一堆类型推导
    hitmanx
        13
    hitmanx  
       2021-01-20 10:59:44 +08:00
    不同的编程范式带来的陌生感。
    XIVN1987
        14
    XIVN1987  
       2021-01-20 11:09:04 +08:00   3
    @myid
    你这说法和书上说的不一样啊

    书上都说能用 std::string,不用 C 风格的字符数组;能用 std::array,不用 C 风格的数组
    focux
        15
    focux  
       2021-01-20 11:29:25 +08:00
    那你还不如看 boost 源码呢
    skyworker
        16
    skyworker  
       2021-01-20 11:32:42 +08:00
    泛型是当时 C++的一个风格, 忘记了好像是相对于"对象 /继承"这种 "运行时多态" 之外, 通过 template 技术来实现 "编译时多态", 不过貌似当时被排斥为"异端"
    auto8888
        17
    auto8888  
       2021-01-20 11:43:29 +08:00
    @shunia IDE 是 qt creator 主题 dark 字体 courier 请指教 /doge
    abc612008
        18
    abc612008  
       2021-01-20 11:47:13 +08:00   9
    @myid 建议直接用 c
    1490213
        19
    1490213  
       2021-01-20 11:48:55 +08:00 via Android
    组里部分老 C++ 代码不好的两个倾向:
    一,追求技巧和花样,县城盖白宫。
    二,半吊子整出的幺蛾子多,配合起来困难。
    shunia
        20
    shunia  
       2021-01-20 11:55:02 +08:00
    @auto8888 #17 我不是 C 程序员,完全不懂哈,我只是觉得您的截图,字体和配色太花眼了,我第一眼看过去就觉得看代码的成本太高。虽然 IDE 只是点缀,但是从某一个角度来说,配合熟练并且本身就更优秀的 IDE,应该相对来说更能提高工作效率。当然这点我有点主观,看看就好。

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

    我不懂 C/C++,所以考虑不到这些 IDE 是否适合对应的工作流。
    shunia
        21
    shunia  
       2021-01-20 11:57:31 +08:00
    ![比如我用 sublime 打开 libwebp 的情况,相对来说要清晰很多吧?]( https://tva1.sinaimg.cn/large/008eGmZEly1gmu0v44k6rj31d90u0b0c.jpg)
    mingl0280
        22
    mingl0280  
       2021-01-20 12:00:46 +08:00   1
    @myid
    我想避免满天飞的 void*,所以才用 template 的……
    因为以前的代码是 C 升级上来的,真的是满天飞的 unnamed type 和 void*以及各种强制类型转换,这种时候你就知道 C++的带类型和语义化的好处了。
    另外,C 风格字符数组这个东西我现在跟我同事说了,不是万不得已不要用,因为有些东西根本不应该被转换为字符数组,而有些东西你用字符数组带来的裸指针的麻烦比用容器更大。
    aihimmel
        23
    aihimmel  
       2021-01-20 12:03:24 +08:00 via Android
    Jirajine
        24
    Jirajine  
       2021-01-20 12:04:22 +08:00 via Android   2
    当你对 c++感到蛋疼的时候,去看看 rust,你会发现一个新世界。
    Leviathann
        25
    Leviathann  
       2021-01-20 12:28:11 +08:00 via iPhone
    @Jirajine 是更蛋疼还是相反。。
    e583409
        26
    e583409  
       2021-01-20 13:08:57 +08:00
    @Jirajine 洗耳恭听
    XIVN1987
        27
    XIVN1987  
       2021-01-20 13:16:13 +08:00
    @Jirajine
    语法和 C 、C++、C#、JAVA 这些 C-like 都不一样,,至少从语法上肯定是个新世界
    AlohaV2
        28
    AlohaV2  
       2021-01-20 13:18:24 +08:00
    template 比 macro 绝大多情况下友好多了,相信我。
    STL 的作用就是让使用者不必关心这些实现细节,除非使用者要讲究细节。
    自己的库封装给用户的时候,不一定 template 就为王,要根据场景而定的。最好的结局是尽管你可能用到了 template,但是用户使用的时候几乎无感。
    nightwitch
        29
    nightwitch  
       2021-01-20 13:31:18 +08:00
    @myid
    在 C++里面 class 和 struct 除了默认的访问和继承权限不一样以及 template class 以外,其他是一个东西
    nnqijiu
        30
    nnqijiu  
       2021-01-20 13:34:30 +08:00
    c 风格和 c++风格混用才是 c++让人蛋疼的地方
    nightwitch
        31
    nightwitch  
       2021-01-20 13:37:36 +08:00
    https://github.com/electronicarts/EASTL
    推荐 EASTL,名字没有混淆过(因为命名空间在 eastl::),虽然不是完整的标准库,但是可读性很好,读起来和普通 c++代码差不多。

    其实标准库没有想象的难,因为标准库的实现的东西都有 cppreference 可以参考,各个模块之间耦合也不深,而且可以多个标准库(libc++,libstdc++,msvcSTL)和仿标准库(eastl, folly)交叉验证着读,除了 iostream 之类的糟粕以外,容器和算法读起来都应该不会有太多困难。
    wdhwg001
        32
    wdhwg001  
       2021-01-20 15:05:29 +08:00 via iPhone
    标准库都难读的话 ranges 岂不是更魔法文字…
    AndyAO
        33
    AndyAO  
       2021-01-20 15:16:55 +08:00
    template 是元编程技术,对于很基础的类库,使用元编程技术能够极大地提升开发效率,但是由于直接对语言本身进行了改动,所以相比起其他的代码,你需要更多的学习才能看懂.

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

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

    以上观点参考自松本行弘的<代码的未来>
    neocanable
        34
    neocanable  
       2021-01-20 15:20:50 +08:00
    哎,我觉得我从来就没有学会过 c++
    yazinnnn
        35
    yazinnnn  
       2021-01-20 15:26:00 +08:00
    rust 不是 c-like ?
    myid
        36
    myid  
       2021-01-20 15:28:42 +08:00
    @abc612008 C++有它的好处。我们不妨取二者最好的部分来用。
    myid
        37
    myid  
       2021-01-20 15:30:33 +08:00
    @nnqijiu 好奇中。举一个小例子?
    @neocanable 你不是一个人在战斗。。。
    myid
        38
    myid  
       2021-01-20 15:41:45 +08:00
    @XIVN1987 绝大多数 C++书这么讲。我信了,直到动手编写代码到了一定量,遇到坑,才醒悟。别盲目相信书。卖瓜的都说瓜甜,卖风油精的讲治百病。C++标准库里的 std::string, std::set 等不见得符合“简单、直接、齐活”的要求。以前对 c-style char array 很不待见,如今领会到了它存在的理由和价值。好比武器,不一定越高级,功能越齐全,就越好越适合。
    l00t
        39
    l00t  
       2021-01-20 16:21:33 +08:00   1
    @myid #36 C++ 和 C 揉在一起就是它最坑的部分。
    myid
        40
    myid  
       2021-01-20 16:24:23 +08:00
    @towry 妙语!赞。
        41
    myid  
       2021-01-20 16:25:52 +08:00   1
    @l00t 把 C++和 C 最混沌最难用最易出错最危险的揉在一起,是最坑的。
    salamanderMH
        42
    salamanderMH  
       2021-01-20 16:38:21 +08:00
    侯捷的《 STL 源码剖析》,看了才知道水很深。
    786375312123
        43
    786375312123  
       2021-01-20 17:17:55 +08:00
    @myid “能用 C 风格的字符数组搞定,就没必要用 std::string 类。”

    啊?
    stirlingx
        44
    stirlingx  
       2021-01-20 19:23:29 +08:00   2
    学一下 erlang,你会发现变量不能赋值
    Narcissu5
        45
    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
        46
    GeruzoniAnsasu  
       2021-01-20 20:47:07 +08:00
    std 是 stl 的命名空间

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

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



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

    根据自己的需求,合理选择这些东西,才是正解。
    codyfeng
        50
    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
        51
    travo  
       2021-01-20 22:03:08 +08:00   1
    这恰恰说明了 C++这门语言很糟糕。
    工具是为了干活,但一种工具如果极其晦涩难用,就该换工具了。
    --------------------------------------------------
    在写 C++的时候,不小心点进 std 标准库的.h 头文件,只是看了一眼它的源代码。
    我去,一堆的 template 操作,一堆的__下划线,一堆的...变参。。。
    仿佛进入了另外一个世界,C++的水真深啊。
    我想如果看懂 std 源码,我觉得差不多也就学成了吧。
    mxalbert1996
        52
    mxalbert1996  
       2021-01-20 22:17:14 +08:00 via Android
    @myid 我觉得可能只有你一个人觉得 C 风格字符串比 std::string 更易懂。
    agagega
        53
    agagega  
       2021-01-20 22:38:16 +08:00 via iPhone   2
    标准库里面的实现当然是在填坑所以代码复杂..而且标准本身可能有些细节作为普通用户也没注意到(比如 iostream 的 api 本身就很复杂)另外还有 std::function 这种本身就需要一点 C++的魔法才能学会的东西。

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

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

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

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

    再比如多维张量中,所有维度都已知长度的小张量可以在堆上分配内存,而有些维度未知长度的大张量可以使用堆内存。这样能得到更高的效率。
    liuminghao233
        57
    liuminghao233  
       2021-01-21 01:24:41 +08:00 via iPhone
    之前看了 asio 的代码头都裂开了
    jsyangwenjie
        58
    jsyangwenjie  
       2021-01-21 03:39:46 +08:00   1
    @myid 这几句话没一句对的。。
    neoblackcap
        59
    neoblackcap  
       2021-01-21 03:45:50 +08:00
    @yazinnnn 受 ML 系的影响更大,里面一堆函数的用法。对类型系统的推崇
    owenliang
        60
    owenliang  
       2021-01-21 09:48:22 +08:00
    个人感觉:精通现代 C++的 template 语法,难度不亚于精通主流机器学习算法的推导与实现。
    laminux29
        61
    laminux29  
       2021-01-21 10:03:57 +08:00
    @codyfeng vector 在有些情况下,会自作主张调用析构函数。
    12101111
        62
    12101111  
       2021-01-21 10:17:01 +08:00
    @ipwx rust? macro_rules! #[proc_macro]
    429839446
        63
    429839446  
       2021-01-21 10:21:44 +08:00
    @nightwitch 在 ms 的系统里会影响 abi, 混用 clang 会出警告..
    codyfeng
        64
    codyfeng  
       2021-01-21 10:38:51 +08:00 via Android
    @laminux29 原来如此,vector resize 需要重新分配空间的时候的确会发生这种情况。可以如此解决
    1 、实现 move constructor
    2 、往 vector 塞东西前 reserve

    这个不能怪 vector,即使自己管理内存,需要重新分配空间时也有同样的问题。
    hobochen
        65
    hobochen  
       2021-01-21 11:32:36 +08:00
    @ipwx 话得反过来说才对,C++是零开销语言里面抽象能力最强的;更强大的抽象能力还是得看看 functional 的那一大堆
    siyemiaokube
        66
    siyemiaokube  
       2021-01-21 11:37:45 +08:00 via iPhone
    @hobochen
    个人感觉 cpp 现在已经非常 functional 了……
    nmap
        67
    nmap  
       2021-01-21 11:40:37 +08:00
    做基础库( stl/boost 等)的人,跟做应用开发的人,不是一个 level 的。。。
    fixend
        68
    fixend  
       2021-01-21 11:45:15 +08:00
    vs 的 stl 的代码风格看起来是很难理解,
    总感觉那代码是做过代码混淆的,为了防止别人抄袭,
    我没记错的话,这库是微软买的。

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

    然后,boost 库才是真会看得怀疑人生,各种模板技巧,大量 N 层嵌套的宏。
    togou
        69
    togou  
       2021-01-21 12:09:59 +08:00
    委员会那帮人 C++ 差不行么? 不说精通 比大部分专家 怕是要好吧
    hobochen
        70
    hobochen  
       2021-01-21 13:38:45 +08:00
    @siyemiaokube 没反射(甚至连编译器反射都没有)怎么和那些 type as data 的语言比啊
    hobochen
        71
    hobochen  
       2021-01-21 13:39:03 +08:00
    @hobochen 编译期
    ipwx
        72
    ipwx  
       2021-01-21 14:09:08 +08:00
    @hobochen 你说得对
    @12101111 rust 也行嘛,是我孤陋寡闻了。
    stevefan1999
        73
    stevefan1999  
       2021-01-21 17:00:43 +08:00
    @ipwx Rust
    dyv9
        74
    dyv9  
       2021-01-21 17:11:57 +08:00
    @shunia 你觉得作者和你用的是一样的 开发工具?太天真了吧。指不定人家的工具自动化水平非常高,写两段伪码剩下的自动翻译成源代码呢。
    dyv9
        75
    dyv9  
       2021-01-21 17:27:37 +08:00
    虽然 我不懂 C++,但我觉得 既然是标准库,一定是一群人讨论后觉得这个方案是适合大部分人,能解决大部分问题的普适方案,如果你的问题很特殊,那我相信你应该已经是专家,知道怎么解决问题,并不必须依赖标准库。
    lakehylia
        76
    lakehylia  
       2021-01-21 17:40:33 +08:00
    提供出去的接口千万不要用 stl,都是泪。。。
    myid
        77
    myid  
       2021-01-21 19:16:49 +08:00
    @mxalbert1996 不是 C 风格字符串更易懂,而是当 C 风格字符串就够用了,那么就用不着 std::string 了。当 C 数组就可以了,用不着非得用 std::vector 。

    std::string 作为处理字符串的类,横向对比 Python, Java 等类似的实现,就显得很残很废很单薄。是不是?
    myid
        78
    myid  
       2021-01-21 19:20:25 +08:00
    @SmartKeyerror C++里不使用 C 字符串和 C 风格数组,是一种迷信。
    mxalbert1996
        79
    mxalbert1996  
       2021-01-21 21:46:54 +08:00 via Android
    @myid 「简单是力量的保证。直白易懂是可持久可维护的护身符。」这是你自己说的,我只能理解为你觉得 C 风格字符串比 std::string 更简单易懂。
    ipwx
        80
    ipwx  
       2021-01-22 09:42:49 +08:00
    @owenliang 噗哈哈哈哈。这个比喻

    我个人的话:template 不说精通,让我写个 stl 没压力。
    机器学习不算大牛,让我推导主流网络结构公式都没压力。我的研究方向是 deep Bayesian network
    ericgui
        81
    ericgui  
       2021-02-05 15:56:29 +08:00
    问个问题:标准库谁写的?
    paxol
        82
    paxol  
       2021-04-30 17:27:33 +08:00
    @skyworker 指的是“奇异递归模板模式”( curiously recurring template pattern,CRTP )吧?把派生类作为模板参数传递给基类
    b00tyhunt3r
        83
    b00tyhunt3r  
       2021-08-09 20:53:54 +08:00
    @ipwx
    不喜欢 rust
    但是你说的这个在 rust 是基操
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3953 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 82ms UTC 05:27 PVG 13:27 LAX 21:27 JFK 00:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86