C_and_CPP 板


LINE

※ 引述《nullpointerk (打滚猫)》之铭言: : 完成後,下面的程式码就都可以运作了,在浏览器上跑跑看吧 : https://godbolt.org/z/wrd7Rv : 这样就优雅解决原 PO 的烦恼了:如果以後要读更多ID我就无解了 看到很恐怖的 code, 推文可能不是那麽清楚就直接发一篇了 你的程式码有几个问题, 有大有小, 後面我列举出来说明. namespace collision 一般在开发的时候应该避免把东西放进命名空间 std 里, 这可能导 致 resolve name 时会模棱两可. 再来因为参数型别本身不定义在 std 内, 所以无法用 ADL (Argument-Dependent Lookup) 来找到这 个函式 namespace std { std::string to_string(const std::string::value_type c) { return {c}; } } // namespace std 比较好的做法就是呼叫的时候不使用 qualified name, 透过 using 把候选名单拉进来 using std::to_string, ::to_string; auto to = to_string(from); 在使用 std::begin() / std::end() 等函式的时候也是一样, 为了 保有更改容器的弹性, 我们不会用 qualified name, 而是先把可能 的名称先 using 进来, 编译器首先会透过 ADL 找寻可用的版本 ( 最好是 overloading), 找不到才会回来用 std 底下的模板来具现 化呼叫实体 (因为後者优先权低). 不过在 C++20 以後开始全面引进 CPO (Customization Point Object) 的概念, 上述所提的 std 函式将会提升为 functor, 在它 们的 call operator 内还是会透过 ADL 找寻呼叫实体, 在那之後 是不是用 qualified name 就不是那麽重要了. 滥用 uniform initialization uniform initialization 原本是用来消歧异的手段, 但在错误的情 境下使用反而会产生语义不明, 例如和 list initialization 混淆 . 如果类别也允许使用 std::initializer_list 来做初始化, 那麽 在接受多个引数的时候你怎麽知道被呼叫的建构子是哪版? 这在 C++17 引进 CTAD (Class Template Argument Deduction) 之後让 情况更恶化了, 而且 uniform initialization 不允许 narrowing conversion, 搞清楚意图再使用会比较好. Barry Revzin: Uniform initialization isn’t https://bit.ly/2X91QDS 顺带一提, 你可以加上编译器选项 --pedantic-errors 看看有无误 解使用方法. 滥用 temporary object lifetime extension 根据 [class.temporary] 2 的描述: 2. The materialization of a temporary object is generally delayed as long as possible in order to avoid creating unnecessary temporary objects. [ Note: Temporary objects are materialized: (2.1) when binding a reference to a prvalue 这边其中一项就是绑定参考的情况, 但这仅限於直接绑定, 间接绑 定是不会获得再延长效果的. 在这里不得不提设计不良的 std::min() 它的宣告如下: template< class T > const T& min( const T& a, const T& b ); 因为参数型别是 ref to const, 所以可以接受 prvalue 做为引数, 而回传值只是把 ref 再传出去而已, 这里的用法和 ?: 运算子差不 多, 不过因为引数的 lifetime 只被延长到函式呼叫结束为止, 所 以回传值其实是 dangling reference. 而且在 C++17 以後保证了 copy elision, 所以已经不需要刻意这样做. 滥用 decltype 虽然 decltype 运算子好像可以省下未来修改程式码的功, 但有没 有想过 decltype 推导出来的型别如果是 ref to const 该怎麽办? 有没有用 type traits 来过滤掉不合法的情况? reference to small object reference 通常会以类似 pointer 的方式去实作, 当呼叫函式使用 pass by reference 传递引数的时候首先要考虑的是: 它的成本是 否低於 pass by value? 在 C++ Core Guidelines 有给出一个参考 F.16: For “in” parameters, pass cheaply-copied types by value and others by reference to const https://bit.ly/39AE728 为了 8 位元物件参数用 pass by reference 是显然不合理的. 意义不明的 forwarding reference 函式 unkonwn_logic_a() 里的参数 ids 型别被定义为 forwarding reference. template <typename IDS> std::string unkonwn_logic_a( decltype(length(std::declval<IDS>())) pcs, IDS &&ids ); 通常我们使用 fwding ref 是用来保留引数的值类别 (value category), 接着用同样的类别来选择可用的多载函式呼叫, 如 length(ids) 呼叫. 不过因为 ref 被绑定之後会变 lvalue ref , 这里还需要使用 std::forward() 把值类别加回来才行. 所以正 确的呼叫应为 length(std::forward<IDS>(ids)); 但因为你压根没 有提供其他接受 rvalue 版本的 length() 函式, 所以在这里用 fwding reference 是多余的. 後话 通常我们在写类别/函式模板时, 情况都是: 因为有复数个实作非常相近, 所以把它们合并在一起 而不是为了泛用而去写模板, 这容易因为没仔细检查 type contraint 而写出很难改的模板. 有个准则就是你有没有透过 SFINAE (Substitution Failure Is Not An Error) 来限缩模板可 用情境. 因为模板内的操作都是基於某种假设而实作, 像是需要有 可被呼叫的成员函式等等, 不符合假设的型别本就不该拿来具现化 造成编译错误. 有一个可能比较少用的标头挡 <iterator> 里面像是 std::size() 就跟你的 length() 角色是一样的, 在实作之前看看标准函式库的 例子就能多少避掉上面提到的问题. --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 223.136.172.53 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1585982593.A.3A8.html ※ 编辑: loveme00835 (223.136.172.53 台湾), 04/04/2020 15:21:45
1F:推 sarafciel: 推,放个假回来就看到两篇好文章 04/06 00:59
2F:推 flysonics: 推 04/06 18:57
3F:推 s4300026: 推 04/07 08:27







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Soft_Job站内搜寻

TOP