C_and_CPP 板


LINE

※ 引述《clonsey1314 (Clonsey)》之铭言: : 最近刚接触vector, 很方便, 省了很多初始化的工作 : 程式码也变得简洁多, 也较好维护 : 但是同时也降低的程式的效能(很明显) : 请问若没有要做太多复杂的增删,是否继续使用array或pointer就好? : 程式码里同时有vector和pointer/array混杂这样的coding style会不会不好? : 谢谢 一般在 std::vector 和 C array 间作选择的考量点主要在元素个数的 决定时机: 如果元素个数在编译时期可以决定, 当然使用 C array 或 std::array; 如果只能在执行时期决定, 才需要考虑 std::vector, 但 也不是预设就使用 STL 容器, 端看你的使用情境. 简单举个例子: 假如我们现在需要一块连续记忆体来储存班上同学的期 末考成绩, 班上同学的数目已知是 50 位, 分数是非负整数, 就可以用 std::array 来定义: using score_type = unsigned; std::array<score_type, 50> scores; 然後可能因为效能需求, 或到某个时机点才需要将这块记忆体配置出来 (lazy initialization), 可以考虑 std::unique_ptr + std::array: std::unique_ptr<std::array<score_type, 50>> scores; 需要注意的是, 这里和 std::unique_ptr<score_type[]> 的差别在於 元素个数的决定时机, 如果想使用後者, 代码的长相需要像这样: std::size_t n; std::cin >> n; auto scores = std::make_unique<score_type[]>(n); 两者表达的语意完全不一样. 另外 std::vector 虽然简化了物件初始 化及复制, 但其附带的可变长度性质, 也不适合用来描述上面的问题. 所以用什麽型别不是问题, 问题是有没有用对型别. 最後整理给你作参 考: (考虑 owning 语意) 元素个数在编译时期决定: 不需要改变大小: std::array<T, N> 元素个数在执行时期决定: 需要改变大小: STL container 不需要改变大小: std::unique_ptr<T[]> 选用何种 STL 容器就看需要哪些操作 (存取方式、存取成本、新增/删 除元素的位置等..) 假如会在後端以外的地方新增元素, std::vector 就不是好的选择. --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 123.193.76.85
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1549042751.A.DB1.html
1F:推 ilikekotomi: 感谢整理与分享 02/02 13:40
2F:→ tomsawyer: 题外话 请问如何存取vector string里面的字元? 02/02 18:02
3F:推 achicn3: s1[0][0]这样吧?楼上 02/02 18:22
4F:推 tomsawyer: 我试试看 谢谢楼上 02/02 18:57
比较好的方式是: using std::next; const std::vector<std::string> vs{"hello"s, "world"s}; const auto idx = 1z; // or const std::ptrdiff_t idx = 1; in pre-c++20 [[assert: idx < size(vs)]]; const std::string_view sv = *next(begin(vs), idx); [[assert: sv[1] == 'o']]; 虽然 std::vector 就有提供 operator[] 用来存取元素, 但并不是所有 的 STL 容器都有提供相同的介面, 当你写下 vs[..] 的时候, 增加了对 容器的需求(requirement), 导致抽换容器实作的时候为了满足(satisfy) 原本的需求必须实作这些介面. 不管是 generic programming 或是想要提供复用性更高的程式码, 对容 器的操作尽可能地局限在迭代器(iterator) 上是比较好的, 使用比较通 用的介面未来扩充性也比较高. 譬如上面这个例子, 若把 next()呼叫改 为: begin(vs) + idx // bad example 这个操作需要迭代器满足 RandomAccessIterator 概念(concept), 因为 std::vector 本身满足 ContiguousContainer, 很容易就会使用到不必要 的操作, 是比较不好的用法. 使用 begin() 让 ADL(argument dependent lookup) 寻找合适的呼叫 (包含自定义函式), 多了 next() 间接呼叫让 ForwardIterator 也能当作引数, 这段码的复用性就大大地提高了. 最後建议透过 std::span 或 std::string_view 甚至是 ranges library 里的适配器(adaptor)来存取容器元素, 也可以减少对容器介面的依赖.
5F:推 allensheng: 最近的文都太专业了吧 02/03 01:43
※ 编辑: poyenc (123.193.76.85), 02/03/2019 17:30:32
6F:推 leoloveivy: 刚转回C/CPP版真D没让我失望XDDD 推个 02/03 19:42







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灯, 水草

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

TOP